B
borpavlenko
Здравствуйте, товарищи!
Пишу серверное многопользовательское приложение.
За основу взял пример отсюда
На всякий случай продублирую код
Итак, сам компонент TCPSocket ожидает подключения в отдельном потоке. При подключении клиента создается клиентский поток, в котором уже выполняется общение с клиентом.
Суть-вопросы.
1. Для закрытия соединения при получении команды 'BYE' используется вызов Terminate, который (как я понимаю) убивает клиентский поток. Правильно ли это? Не надо ли вызывать методы Disconnect, Close класса ClientSocket ? Проясните этот момент, кто знает.
2. Для меня сейчас более актуально разобраться в следующем:
если клиент не отправляет команду 'BYE', а просто вырубается, рвется соединение и т.п., то цикл while в TcpServer1Accept начинает бесконечно гонять по кругу. Т.е. получается, что сокет висит в каком-то неопределенном состоянии (пробовал определять эту ситуацию проверкой ClientSocket.Connected, но ничего не вышло, остается TRUE), пользовательский поток гоняет по кругу цикл, который уже ничего не сделает, хотя должен умереть.
Как правильно отследить и обработать эту ситуацию?
В общем, научите правильно закрывать соединения со стороны сервера во всех случаях. Заранее спасибо.
Пишу серверное многопользовательское приложение.
За основу взял пример отсюда
Ссылка скрыта от гостей
На всякий случай продублирую код
Код:
…
type
TMyClientThread = class(TClientSocketThread)
private
FCmd: String;
FData: String;
protected
procedure SyncProc; override;
end;
…
procedure TMyClientThread. SyncProc;
begin
if FCmd = ‘CLR’ then
Form1.ListBox2.Clear
else
if FCmd =’TXT’ then
Form1.ListBox2.Items.Add(FData)
else
if FCmd = ‘BYE’ then begin
Terminate;
Form1.ListBox1.Items.Add(‘Отключился:’+ ClientSocket.RemoteHost);
end;
else
if FCmd = ‘’ then
Form1.ListBox1.Items.Add(‘Подключился:’+ ClientSocket.RemoteHost);
end;
procedure TForm1.RormCreate(Sender: TObject);
begin
Caption:=’Сервер’;
ListBox1.Clear;
ListBox2.Clear;
TcpServer1.LocalPort :=’5050’;
TcpServer1.Active := ‘True’;
end;
procedure TForm1. TcpServer1GetThread(Sender: TObject;
var ClientSocketThread: TClientSocketThread);
begin
ClientSocketThread:=
TMyClientThread.Create(TcpServer1.ServerSocketThread);
end;
procedure TForm1. TcpServer1Accept(Sender: TObject;
ClientSocket:TCustomIpClient);
begin
with (ClientSocket.GetThreadObject as TMyClientThread) do begin
FCmd:=’’;
ExecuteSyncProc;
while not Terminated do begin
FCmd:= ClientSocket.Receiveln;
if FCmd = ‘TXT’ then
FData:= ClientSocket.Receiveln;
if FCmd <> ‘’ then
ExecuteSyncProc;
end;
end;
end;
Итак, сам компонент TCPSocket ожидает подключения в отдельном потоке. При подключении клиента создается клиентский поток, в котором уже выполняется общение с клиентом.
Суть-вопросы.
1. Для закрытия соединения при получении команды 'BYE' используется вызов Terminate, который (как я понимаю) убивает клиентский поток. Правильно ли это? Не надо ли вызывать методы Disconnect, Close класса ClientSocket ? Проясните этот момент, кто знает.
2. Для меня сейчас более актуально разобраться в следующем:
если клиент не отправляет команду 'BYE', а просто вырубается, рвется соединение и т.п., то цикл while в TcpServer1Accept начинает бесконечно гонять по кругу. Т.е. получается, что сокет висит в каком-то неопределенном состоянии (пробовал определять эту ситуацию проверкой ClientSocket.Connected, но ничего не вышло, остается TRUE), пользовательский поток гоняет по кругу цикл, который уже ничего не сделает, хотя должен умереть.
Как правильно отследить и обработать эту ситуацию?
В общем, научите правильно закрывать соединения со стороны сервера во всех случаях. Заранее спасибо.