TCP为每条连接建立了7个定时器。按照它们在一条连接生存期内出现的次序,简要介绍如下。
1."连接建立"定时器在发送syn报文段建立一条新连接时启动,如果没有在75秒内收到响应,连接建立将中止。
2.“重传”定时器在TCP发送数据时设定。如果定时器已超时而对端的确人还未到达,TCP将重传数据。重传定时器的值是动态
计算的,取决于TCP为该连接测量的往返时间和该报文段已被重传的次数。
3.“延迟ACK”定时器在TCP收到必须被确认但无需马上发出确认的数据时设定。TCP等待200ms后发送确认响应。如果在这
200ms内,有数据要在该连接上发送,延迟的ACK响应就可随着数据一起发送回对端,称为捎带确认。
4.“持续”定时器在连接对端通告接收窗口为0,阻止TCP继续发送数据时设定。由于连接对端发送的窗口通告不可靠,允许TCP
继续发送数据的后续窗口更新有可能丢失。因此,如果TCP有数据要发送,但对端通告接收窗口为0,则持续定时器启动,超
时候向对端发送1字节的数据,判断对端接收窗口是否打开。与重传定时器类似,持续定时器的值也是动态计算的,取决于连续
的往返时间,在5秒到60秒之间取值。
5.“保活”定时器在应用进程选取了插口的SO_KEEPALIVE选项时生效。如果连接的连续空闲时间超过2小时,保活定时器超时,
向对端发送连接探测报文段,强迫对端相应。如果收到了期待的响应,TCP可确定对端主机工作正常,在该连接再次空闲超过
2小时之前,TCP不会再进行 保活测试。如果收到的是其他响应,TCP可确定对端主机已重启。如果联系若干次保活测试都未
收到响应,TCP就假定对端主机已崩溃,尽管它无法区分是主机故障还是连接故障。
6.FIN_WAIT_2定时器。当某个连接从FIN_WAIT_1状态变迁到FIN_WAIT_2状态,并且不能再接收任何新数据时,FIN_WAIT_2
定时器启动,设为10分钟。定时器超时后,重新设为75秒,第二次超时候连接 被关闭。加入这个定时器的目的是为了避免如果
对端一直不发送FIN,某个连接会永远滞留在FIN_WAIT_2状态。
7.TIME_WAIT定时器,一般称为2MSL定时器。2MSL指两倍的MSL(最大报文段生存时间)。当连接转移到TIME_WAIT状态,
即连接主动关闭时,定时器启动。连接进入TIME_WAIT状态时,定时器设定为1分钟,超时后,TCP控制块和Internet PCB 被
删除,端口号可重新使用。
TCP包含两个定时器:一个函数没200ms调用一次,一个函数没500ms调用一次。延迟ACK定时器与其他6个定时器有所不同:
如果某个连接上设定了延迟ACK定时器,那么下一次200ms定时器超时后,延迟的ACK必须被发送。其他的定时器每500ms
递减一次,计数器为0时,就触发相应的动作。
代码介绍
当某个连接的TCP控制块中的TF_DELACK标志置位时,允许该连接使用延迟ACK定时器。TCP控制块中的t_timer数组
包含4个TCPT_NTIMERS计数器,用于实现其他的6个定时器,下图列出了数组的索引。
t_timer中每条记录,保存了定时器的剩余值,以500ms为计时单位。如果等于0,则说明对应的定时器没有设定。由于
每个定时器都是短整型,所以定时器最大值智能设定16383.5秒。
请注意,上图中利用4个定时计数器实现了6个TCP定时器,这是因为有些定时器彼此是互斥的。下面我们首先区分下
计数器与定时器。TCPT_KEEP计数器同时实现了保活定时器和连接建立定时器,因为这两个定时器永远不会同时出现
在同一条连接上。类似,2MSL定时器和FIN_WAIT_2定时器都由TCPT_2MSL计数器实现,因为一条连接在同一时间内
只可能处于其中一种状态。下图第一行小结了7个TCP定时器的实现方式,第二行和第三行列出了其中4个定时器初始化
时用到的3个全局变量和2个常量。