一 建立连接时
1.建立连接(connection establishment)定时器:
在发送一个 SYN报文段建议一个新的连接时启动这个定时器,如果在75秒内没有收到响应,连接建立将终止。
二 传输数据时
2.重传(retransmission)定时器:
在TCP发送数据时设定,如果定时器已经超时而对端的确认还未到达,TCP将重传数据。重传定时器的值(即TCP等待对端确认的时间)是动态计算的,取决于TCP为该连接测量的往返时间和该报文段已经被重传的次数
3.延迟应答(delayed ACK)定时器:
接收端收到数据必须确认但无需马上发出确认的数据时设定。TCP等待200ms后发出确认响应(如果在200ms在此收到了数据,在这个延迟ACK的定时器将重置成200ms)。如果,在这200ms内,接收端想发数据给对端,那么这个延迟ACK就随着这个数据一起发送到对端(称为:捎带确认)
4.坚持(persist)定时器:
在接收端通告接受窗口为0,阻止TCP继续发送数据时设定。用于接收端发送的窗口通告不可靠(只有数据才会被确认,ACK不会被确认),允许TCP发送数据的后续窗口更新有可能丢失。因此,如果TCP有数据要发送,但接收端通告接受窗口为0。则坚持定时器启动,超时后向接受端发送一个字节的数据,判断接受端的窗口是否打开。与重传定时器类似。坚持定时器的值也是动态计算的,取决于连接的往返时间,在5s~6s之间取值。
5.保活(keepalive)定时器:
如果连接的连续空闲时间超过两个小时,保活定时器超时,向对端发送连接的探测报文,强迫对端响应,如果收到期待的响应,TCP可确定对端的主机工作正常,否则,TCP可确定对端主机以重启或者故障。在通信进程(通过setsockopt函数)选取了socket的SO_KEEPALIVE选项时生效。但是不太实用,2个小时太长了,一般都独自设置心跳协议来探测是否保持连接的。
三 断开连接时
6.FIN_WAIT_2 定时器:
主动关闭的一端调用完 close以后(即发送FIN给被动关闭的一端,并且收到其对FIN的确认ACK)则进入FIN_WAIT_2状态。
如果这个时候因为网络突然断掉,被动关闭的一段宕机等原因,导致主动关闭的一端接受不到被动关闭的一端发来的FIN,主动关闭的一端总不能一直等着(毕竟不是真爱),这时候设置FIN_WAIT_2 定时器,如果这个定时器超时的时候 还没有收到被动关闭的一端发过来的FIN,那么那么直接释放这个连接。
7.TIME_WAIT 定时器【也称为 2MSL(max segment lifetime , 报文段最大生存时间)定时器】:
即两倍最大报文段生存时间定时器(windows:MSL = 2min, linux:MSL = 60s, UNIX: MSL=30s)。主动关闭连接的一端最后进入的状态不是直接变成CLOSED状态而是TIME_WAIT状态。原因1:如果被动关闭的一端在超时时间内没有收到最后一个ACK,则会重发最后的FIN, 2MSL等待时间保证了重发的FIN会被被动关闭的一端收到且重新发送过一个ACK;原因2:在2MSL等待时间时,任何迟到的报文段会被接受并丢弃,防止老的TCP连接的包 在新的TCP连接里面出现。
三次握手和四次挥手的定时器工作图
更多的C/C++ linux编程我会在下面的文章中陆续的分享,也可以关注‘奇牛学院’
来一起讨论