当然,在一些轻量的TCPIP协议栈中,并不会为每个报文都使用独立的超时计时,如LWIP,每个TCP控制块只有一个超时计时值,每收到一个新的ACK都会被清零重新计时,在RTO后都还没收到ACK,便会把UNACK队列中的所有数据都会回迁至UNSENT队列 。
12.9.2 坚持定时器坚持(persist)定时器使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口 。
先来了解下窗口探查 。
窗口探查(window probe):
当接收方TCP缓冲区没有剩余空间后,在ACK中会通知发送方window=0,此时发送方就暂停发送数据 。
当接收方TCP缓冲区又有空间后,会再次发送一个ACK,告知其剩余缓冲区大小,可以接受新的数据包了,这个ACK叫做窗口更新 。
TCP接收方则等待新的数据包过来 。但是如果这个窗口更新的ACK丢失了,那么会出现两端互相等待:接收方等待新的数据包,因为他已经通知对端新的window大小了,而发送方则还在等待窗口更新,因为它还认为对端窗口为0 。
坚持定时器(Persist Timer)就是为了解决这个问题而设计的 。
发送方使用一个坚持定时器来周期性的向接收方查询,以便发现窗口已经增大 。这些从发送方发出的查询报文段被称为窗口探查(window probe) 。
窗口探查包含一个字节,TCP总是允许发送已关闭窗口之后一个字节的数据 。
发送方在收到window=0的通知后就开启这个定时器,如果这个定时器的时间到还没收到接收方的窗口更新,那么它就探查这个空的窗口以决定窗口是否丢失 。
窗口探查的时间间隔可以逐步增大,一定次数后,可以认为对端已经关闭连接 。
12.9.3 保活定时器保活(keepalive)定时器可检测到一个空闲连接的另一端何时崩溃或重启,而不是一直永久地等下去 。
初始超时通常为2小时,如果2小时没有收到客户端的数据,服务端就发送一个探测报文,以后每隔75秒发送一次,如果连续发送10次探测报文段后仍没有收到客户端的响应,服务器就认为客户端出现了故障,就可以终止这个连接 。(具体查看各个TCPIP协议栈的具体实现)
TCP保活探测报文:是将之前TCP报文的序列号减1,并设置1个字节,内容为“00”的应用层数据 。
注意:保活机制并不是 TCP 规范中的一部分,对此主机需求RFC 1122给出了三个理由:
- 在出现短暂的网络错误的时候,保活机制会使一个好的连接断开 (接收保活报文的一端可能只是因为一时的故障没有响应,故障可能很快会恢复,但另一端并不知情,他只知道自己发送的保活报文没有收到回应,那么就错误地认为对方不在工作了,于是断开连接);
- 保活机制会占用不必要的带宽 (因为不影响数据流,需要额外的报文的开销);
- 在按流量计费的情况下会在互联网上花掉更多的钱 (同样因为使用额外的报文) 。
12.10 常用选项字段分析12.10.1 MSSMSS:Maximum Segment Size (MSS) Option
参考:RFC 1122, chap 4.2.2.6
一般情况下,通信双方在建立连接时,SYN Segment中会携带MSS Option,MSS指明本端可以接受的最大长度的TCP Segment(Payload,不含TCP Header),也就是说,对端发送数据的长度不应该大于MSS(单位Byte) 。
- 首先要明确一点,MSS并非和对端协商的值,而是对对端发送数据长度的“限制”,表明在整个TCP连接期间,都不会接收长度大于MSS的TCP Segment 。
- 如果收到的SYN中没有MSS,将使用默认值536 。MSS Option的Value字段长度固定为16bit,所以MSS最大值为65535(单位Byte) 。因此,网络中所有设备都被要求,必须能够处理大小小于576Byte的数据包(IP Header + TCP Header + Default MSS 最小值为 576 Byte)
经验总结扩展阅读
- 哪个星座是是天蝎座的情劫
- 水表最后一位红色是1吨还是0.1吨
- 龙舌兰酒为什么不能直接喝
- 长虫是什么动物
- 烈火军校董小姐扮演者是谁?
- 牛仔裤38码是多少尺?
- 小丑女的电影是哪一个?
- 唐艺昕演的穿越剧叫什么名字?
- 霉茶叶有什么用途
- bollycon是哪个国家的美瞳品牌?