IdTCPServer和IdTCPClient断线问题(100分)

  • 主题发起人 主题发起人 ysfy
  • 开始时间 开始时间
Y

ysfy

Unregistered / Unconfirmed
GUEST, unregistred user!
近来在做一个项目,要让客户端长期在线,使用Timer每隔10秒检测在线状态,
procedure TClientFrmMain.Timer1Timer(Sender: TObject);
begin

if Client.Connected then
try
Client.WriteLn('CLIENT ONLINE ');//客户端发信息给服务端,表明自己在线
except
client.Disconnect;
end;
end;

procedure TClientHandleThread.Execute;
begin//客户端接收线程
while not Terminated do
begin
if not ClientFrmMain.Client.Connected then
Terminate
else
try
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
Synchronize(HandleInput);
except
if not Terminated then Terminate;
if Assigned(ClientFrmMain.Client) then
ClientFrmMain.Client.Disconnect;
end;
end;
end;

遇线路不稳定时问题就出来了,情况分两种:1、客户端断线。2、服务端断线。
如果出现第一种情况时Client能自动断开;如果出现第二种情况时却无法抛出异常,Client不能自动断开,也就是说:Client.WriteLn('CLIENT ONLINE ') 能正常运行!有什么办法能让Client自动断开?
 
我也碰过这样的情况,所以说TCP也不是100%可靠,但这也只是比较少得,因为你在不停地Client.WriteLn('CLIENT ONLINE '),估计也就1分半钟左右会断开.保险一点的话,服务器也发心跳信息.
 
IdTCPServer有个OnException事件,在里面捕获诸如Socket Error错误事件就可以监视到客户端的情况,如果你的客户端是通过网线、网卡上网连接服务器的话(非无线的上网方式),服务器会检测出来的(之前我就做过这样的项目),虽然不能立即检测出来,但所用的时间并不长,远远<1分钟的。
你可以通过拔掉客户端的网线来测试。
TCP连接还是非常可靠的。
 
可能是xfeiffer没碰到这种情况吧,我做了几次测试,确实会有这种情况出现,明明拔了网线,但客户端仍然有段时间还可以发信息而不出现任何错误,有可能是INDY的特性.
 
试验了很长时间,才把这个问题搞清楚,对于这种线路不稳定的网络,在做客户端心跳包时我采用了一个自认为是巧妙的方法,客户端再做一个时间线程,它不断读当前时间,当偶数秒(即second mod 2 为0)时,向服务端发一个Client.WriteLn('CLIENT ONLINE '),同时开启timer时钟(时钟间隔为1秒),客户端的接收线程如果读到了服务端返回的&quot;CLINET ONLINE&quot;时就关掉timer时钟,而timer时钟在这里起一个计数器的作用,比如在计数30次后就可认为客户端已与服务端断开了,可idTCPClient.disconnect!
服务端的心跳也可同上。做出后效果很好。
 
实际用不上再做一个线程,一个Timer就够用了,我一直是用一个Timer.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部