S sxzcm Unregistered / Unconfirmed GUEST, unregistred user! 2004-06-08 #1 我试过thread.connection.CheckForGracefulDisconnect和CheckForDisconnect,竟然都认为该客户连接正常。 不采用客户端定时报告信息的方式,还有别的检测手段吗?
我试过thread.connection.CheckForGracefulDisconnect和CheckForDisconnect,竟然都认为该客户连接正常。 不采用客户端定时报告信息的方式,还有别的检测手段吗?
E element Unregistered / Unconfirmed GUEST, unregistred user! 2004-06-08 #3 1层物理层都断,3层不会马上知道,idTcpserver会在30-90秒后有断开提示。建议采用定时报告的方式。
S sxzcm Unregistered / Unconfirmed GUEST, unregistred user! 2004-06-08 #4 我都等了好长时间(3分钟有了)也没有收到disconnect事件。有人提出利用获取客户端IP的方法,但是connect.socket.binging.peerip是否一连接就固定了,也不能用来判断。就是找到了,ping回去成功也不见得说明客户连接还存在,因为有的客户端是固定IP,临时断开1分钟,再连接上了ip也不变
我都等了好长时间(3分钟有了)也没有收到disconnect事件。有人提出利用获取客户端IP的方法,但是connect.socket.binging.peerip是否一连接就固定了,也不能用来判断。就是找到了,ping回去成功也不见得说明客户连接还存在,因为有的客户端是固定IP,临时断开1分钟,再连接上了ip也不变
L LeeChange Unregistered / Unconfirmed GUEST, unregistred user! 2004-06-09 #5 可以考虑用TCP自己的保活定时器,他的作用是每隔一段时间检查一下连接是否正常,如果不正常则报告给应用层。 用下面的方法试试,理论上应该是对的,偶没有实际测试: 先 uses WinSock; 在TCPServer的OnConnection事件里加上如下的片段: procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); type TCP_KeepAlive = record OnOff: Cardinal; KeepAliveTime: Cardinal; KeepAliveInterval: Cardinal end; var Val: TCP_KeepAlive; Arg: Integer; begin Val.OnOff:=1; Val.KeepAliveTime:=xxx; Val.KeepAliveInterval:=xxx; Arg:=Integer(@Val); ioctlsocket(AThread.Connection.Socket.Binding.Handle, $80000000 or $18000000 or 4, Arg); end; TCP_KeepAlive里的参数的意义是显而易见的,就不多说了。 然后连接将自动按指定间隔测试是否正常,作为应用程序可以在TCPServer的OnException里守着就行了。
可以考虑用TCP自己的保活定时器,他的作用是每隔一段时间检查一下连接是否正常,如果不正常则报告给应用层。 用下面的方法试试,理论上应该是对的,偶没有实际测试: 先 uses WinSock; 在TCPServer的OnConnection事件里加上如下的片段: procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); type TCP_KeepAlive = record OnOff: Cardinal; KeepAliveTime: Cardinal; KeepAliveInterval: Cardinal end; var Val: TCP_KeepAlive; Arg: Integer; begin Val.OnOff:=1; Val.KeepAliveTime:=xxx; Val.KeepAliveInterval:=xxx; Arg:=Integer(@Val); ioctlsocket(AThread.Connection.Socket.Binding.Handle, $80000000 or $18000000 or 4, Arg); end; TCP_KeepAlive里的参数的意义是显而易见的,就不多说了。 然后连接将自动按指定间隔测试是否正常,作为应用程序可以在TCPServer的OnException里守着就行了。
L LeeChange Unregistered / Unconfirmed GUEST, unregistred user! 2004-06-09 #6 心里没底,怕WinSock 1不支持,你最好还是用类似下面的片段吧。 uses WinSock2; procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); type TCP_KeepAlive = record OnOff: Cardinal; KeepAliveTime: Cardinal; KeepAliveInterval: Cardinal end; var Val: TCP_KeepAlive; Ret: DWord; begin Val.OnOff:=1; Val.KeepAliveTime:=xxx; Val.KeepAliveInterval:=xxx; WSAIoctl(AThread.Connection.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4, @Val, SizeOf(Val), nil, 0, @Ret, nil, nil) end;
心里没底,怕WinSock 1不支持,你最好还是用类似下面的片段吧。 uses WinSock2; procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); type TCP_KeepAlive = record OnOff: Cardinal; KeepAliveTime: Cardinal; KeepAliveInterval: Cardinal end; var Val: TCP_KeepAlive; Ret: DWord; begin Val.OnOff:=1; Val.KeepAliveTime:=xxx; Val.KeepAliveInterval:=xxx; WSAIoctl(AThread.Connection.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4, @Val, SizeOf(Val), nil, 0, @Ret, nil, nil) end;
S sxzcm Unregistered / Unconfirmed GUEST, unregistred user! 2004-06-09 #10 第二种好像也不行,不知道是否和indy配合不好还是这些函数需要初始化
S sxzcm Unregistered / Unconfirmed GUEST, unregistred user! 2004-06-09 #12 sorry,我错了,刚才测试第二种方法没有给参数赋值,现在赋值正确了,6000=6秒,拔掉网线6秒立即报告断开。成了了。祝贺大家,LeeChange劳苦功高,领得160分,element也说得有理,分40分。圆满完成
sorry,我错了,刚才测试第二种方法没有给参数赋值,现在赋值正确了,6000=6秒,拔掉网线6秒立即报告断开。成了了。祝贺大家,LeeChange劳苦功高,领得160分,element也说得有理,分40分。圆满完成