我该怎么办呢?他已经困扰我多日了。
请各位大侠指点。谢了我用D5写了一个Socket的程序,服务器ServerSocket采用stThreadBlocking模式,在ServerSocket.OnGetThread事件中创建一个自己定义的TServerClientThread:
procedure TForm1.ssGetThread(Sender: TObject; ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread:= TSocketCli.Create(ClientSocket); //(SocketThread);
end;在TSocketCli的ClientExecute方法中执行数据处理(精简):
procedure TSocketCli.ClientExecute;
var
Stream : TWinSocketStream;
Buffer : array[0..99] of Char;
begin
while ((not Terminated) and ClientSocket.Connected) do
begin
Stream := TWinSocketStream.Create(ClientSocket, 3000);
try
if Stream.WaitForData(3000) then
begin
FillChar(Buffer, 100, 0);
if Stream.Read(Buffer, 80) <> 0 then
begin
Str1:= String(Buffer);
Synchronize(GetMsg);
end;
end;
except
;
end;
Stream.Free;
except
;
end;
end;
end;但是当客户端执行Close后,while ((not Terminated) and ClientSocket.Connected) do 中的ClientSocket.Connected永远为True,导致服务器的线程不能终止,也就是说服务器不能知道Client已经Close。
我该怎么办呢?他已经困扰我多日了。
请各位大侠指点。谢了
请各位大侠指点。谢了我用D5写了一个Socket的程序,服务器ServerSocket采用stThreadBlocking模式,在ServerSocket.OnGetThread事件中创建一个自己定义的TServerClientThread:
procedure TForm1.ssGetThread(Sender: TObject; ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread:= TSocketCli.Create(ClientSocket); //(SocketThread);
end;在TSocketCli的ClientExecute方法中执行数据处理(精简):
procedure TSocketCli.ClientExecute;
var
Stream : TWinSocketStream;
Buffer : array[0..99] of Char;
begin
while ((not Terminated) and ClientSocket.Connected) do
begin
Stream := TWinSocketStream.Create(ClientSocket, 3000);
try
if Stream.WaitForData(3000) then
begin
FillChar(Buffer, 100, 0);
if Stream.Read(Buffer, 80) <> 0 then
begin
Str1:= String(Buffer);
Synchronize(GetMsg);
end;
end;
except
;
end;
Stream.Free;
except
;
end;
end;
end;但是当客户端执行Close后,while ((not Terminated) and ClientSocket.Connected) do 中的ClientSocket.Connected永远为True,导致服务器的线程不能终止,也就是说服务器不能知道Client已经Close。
我该怎么办呢?他已经困扰我多日了。
请各位大侠指点。谢了
通常,如果每个客户端的Socket关闭后,服务器的ServerSocket会自动Free关闭后的客户端的线程,也就是说,客户端的Socket关闭不会触发ServerSocket的OnGetThread事件。
其实你可以在ServerSocket的OnClientDisconnect事件上检查Client是否关闭,你可以参考这段代码:
procedure TFrmMCS.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
ClientConnectCount: integer;
con: integer;
begin
ClientConnectCount := ServerSocket1.Socket.ActiveConnections;
with RichEdit3 do
begin
SelAttributes.Color := clBlack;
RichEdit3.Refresh;
Lines.Add(Socket.RemoteHost +' is exist the Chating room');
end;
for con := 0 to ServerSocket1.Socket.ActiveConnections -1 do
if Socket = ServerSocket1.Socket.Connections[con] then
begin
ComboBox1.Items.Delete(con);
ClientConnectCount := ClientConnectCount -1;
end;
StaticText4.Caption := 'Total ' +inttostr(ClientConnectCount) +'Client(s) Connected Chat Server';
end;
這樣服務器端不會死掉了。而且會自動結束和客戶端的連接並復位。
我已经找到原因了。
是我对SOCKet的编程还不熟悉,我看了TWinSocketStream的源代码。WaitForData其实是调用了IO复用Select。所以只要将Stream.WaitForData(3000) 中的时间值调整到一个很大的值就可以了,这样就能在没有数据传送的时候,线程阻塞在WaitForData,当有数据传送时,WaitForData返回,然后调用Stream.Read读取数据,如果读出数据长度为0,表示客户端关闭,如果数据长度不是0,表示使正常数据传送。