坚持定时器(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)
- IPv4网络中,MSS的典型取值为1460 , 1460Byte + 20Byte IP Header + 20Byte TCP Header = 1500Byte = 以太网典型MTU;
- IPv6网络中,典型MSS取值为1440;另外,如果MSS=65535,表示MSS = PMTU - 60
在标准的TCP实现中 , 使用的是累加式的ACK,例如“ACK Num = n”代表对序列号n以前的Bytes进行确认 。但是,显然,这样将无法对不连续的Segment进行确认 。此外 , 当出现不连续Segment时,还会导致TCP的接收队列出现一个“坑”,不将这个坑填上,坑后的数据就无法交付给应用程序 。
为解决上述问题,TCP定义了SACK Option,可以使TCP接收者将这个“坑”的位置通告给发送者,让其对这一段数据进行重传 。
注意:若要使用SACK特性 , 必须在建立连接时,在SYN Segment中附加上SACK-Permitted Option,以此告知对方自己支持SACK 。
SACK-Permitted Option格式如下所示:
Kind = 4Length = 2SACK Option格式如下所示:
- SACK Option通过“Left Edge ~ Right Edge”,指定了一个或多个范围的Seq Num,称为SACK Block,指明了处于“坑”后面(或坑之间)的、已成功接收的Bytes 。
- 由于TCP Header最长为60 Byte,因此SACK Option中最多只能包含4个SACK Block 。
- 终端A收到了TCP数据流中的Seq Num为0 至 1452、2905 至 4096的字节,但缺少了1453 至 2904;
- 终端A向B发送ACK Segment,其中ACK Num=1453、SACK Option=2905 至 4097,表明它已经收到了数据流中的Seq Num为2905 至 4096的字节,但没有还没收到1453 至 2904;
推荐阅读
- vulnhub靶场之DOUBLETROUBLE: 1
- 亚索怎么玩呢(亚索大招怎么才能释放)
- 如何打好亚索(亚索的打法技巧)
- 无期迷途钻石获取途径有哪些
- 传奇九层妖塔祖玛阁怎么走(传奇祖玛阁攻略)
- 【深入浅出 Yarn 架构与实现】2-4 Yarn 基础库 - 状态机库
- 【Azure API 管理】Azure APIM服务集成在内部虚拟网络后,在内部环境中打开APIM门户使用APIs中的TEST功能失败
- DNF里浓缩的异界精髓怎么获得(浓缩的异界精髓作用)
- 小孩沉迷手机网络游戏怎么办(儿童玩手机游戏沉迷怎么办)
- 带你了解NLP的词嵌入