有人告诉我IdCmdTCPClient怎么知道IdTCPServer意外中断了么? 怎么在两者间实现一问一答? ( 积分: 100 )

  • 主题发起人 主题发起人 陆波
  • 开始时间 开始时间

陆波

Unregistered / Unconfirmed
GUEST, unregistred user!
1。有人告诉我IdCmdTCPClient怎么知道IdTCPServer意外中断了么? 怎么在两者间实现一问一答?[:(!]
2。 我在IdCmdTCPClient用过Writeln/Readln,但当IdTCPServer没应答时,客户端readln会停顿一段时间没反应,readtimeout后才反应,怎么避免停顿?
 
在TCP中有一个Keep-alive的机制可以检测死连接,原理很简单,TCP会在空闲了一定时间后发送数据给对方:
1.如果主机可达,对方就会响应ACK应答,就认为是存活的。
2.如果可达,但应用程序退出,对方就发RST应答,发送TCP撤消连接。
3.如果可达,但应用程序崩溃,对方就发FIN消息。
4.如果对方主机不响应ack, rst,继续发送直到超时,就撤消连接。这个时间就是默认
的二个小时。
在connect中加入下面代码
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;
心跳函数:
客户端定时向服务器发送数据,表示自己存活着。在固定的时间内,服务器没有收到消息,就认为客户端已经断开,并释放连接。而这个过程也可以是双方的。即两边都有心跳机制。
第二个一个是能够以最合适的速度检测出连接异常,进入相应的异常处理,一方面可以尝试确定最短等待时间。
 
Val.KeepAliveTime:=xxx;
Val.KeepAliveInterval:=xxx;
应怎么设置???我很菜啊,分别代表什么意思?
这个能在IdCmdTCPClient中使用么?AThread.Connection.Socket.Binding.Handle应改为什么好?
 
KeepAliveTime 值控制 TCP/IP 尝试验证空闲连接是否完好的频率。如果这段时间内没有活动,则会发送保持活动信号。如果网络工作正常,而且接收方是活动的,它就会响应。如果需要对丢失接收方敏感,换句话说,需要更快地发现丢失了接收方,请考虑减小这个值。如果长期不活动的空闲连接出现次数较多,而丢失接收方的情况出现较少,您可能会要提高该值以减少开销。

缺省情况下,如果空闲连接 7200000 毫秒(2 小时)内没有活动,Windows 就发送保持活动的消息。通常,1800000 毫秒是首选值,从而一半的已关闭连接会在 30 分钟内被检测到。

KeepAliveInterval 值定义了如果未从接收方收到保持活动消息的响应,TCP/IP 重复发送保持活动信号的频率。当连续发送保持活动信号、但未收到响应的次数超出 TcpMaxDataRetransmissions 的值时,会放弃该连接。如果期望较长的响应时间,您可能需要提高该值以减少开销。如果需要减少花在验证接收方是否已丢失上的时间,请考虑减小该值或 TcpMaxDataRetransmissions 值。

缺省情况下,在未收到响应而重新发送保持活动的消息之前,Windows 会等待 1000 毫秒(1 秒)。

KeepAliveTime 根据你的需要设置就行,比如10分钟,注意要转换成MS。
XXX代表这个间隔值得大小
 
后退
顶部