在网上找了一篇tcp中常见定时器还不错的文章,这里转载一下。
tcp中的常见定时器
(1)超时重传定时器
tcp的靠谱特性,通过确认机制,保证每一个包都被对方收到,那么什么时候需要重传呢?就是靠这个超时重传定时器,每次发送报文前都启动这个定时器,如果定时器超时之前收到了应答则关闭定时器,如果没收到就重发该报文,并重置定时器。
(2)建连定时器
和重传定时器类似,发送syn时,为了防止被丢弃,一段时间不回复ack也会重传。
(3)TIME_WAIT(2MSL)定时器
主动发送fin的一端,在接收到对端的ack报文后会进入TIME_WAIT等待自状态,一方面是防止自己回复对方fin的ack被丢掉了,对方无法释放资源,给对方一次重新发送fin的机会(对方等1MSL发现没回+又发送fin(最多耗时1MSL收到)),另一方面是防止刚释放的端口被新建立的连接用上,刚好又有老连接的报文迟到被新连接误用。tcp是一群讲究公平的生物,他们总是期望两边的资源尽量对等,一端释放的时候尽量确保对方也释放,但有时候对端死活没响应,那也不能死等。通常的做法是,我想释放资源了,那么我告诉你一声,等收到你回复了,我就知道你已经释放了,那么我也释放资源。但是有时候,等了一段时间还没收到回复,那就认为是中间传话的系统出问题了,那我再通知一次,再过一段时间,还不回复,那就认为你自己偷偷释放资源了,所以我也不等了,释放资源。TIME_WAIT为了确定对方能释放资源,多等一会儿自己再释放。
(4)坚持定时器
如果发送方数据发送的比较快,接收方处理的比较慢,那么接收方的缓存队列可能会满,这时没法接收新数据了,会将窗口值为0通知给发送方,而发送方将不再发送数据。过一段时间接收方处理完了,队列有了空闲,又把窗口调大,通知给发送方,但这个报文可能被不可靠的链路丢掉,而这个是不会确认和重传的,这样发送方就一直认为接收方的窗口为0,一直等待下去了。为此有了坚持定时器,发送方接收到0窗口就会启动该定时器,定期的询问窗口值变为多少了。
(5)保活定时器
不懂为什么起名叫保活定时器,其实是起的探测作用,定时发送探测报文,探测对端是否还活着,防止资源被白白占用。如客户端和服务器建立连接,客户端直接断电,那么如果没有这个探测,那么服务器会认为这个客户端还在,对应连接的资源就不会释放。有了这个探测,如果客户端已经重启了,会直接回复复位报文给服务器,服务器就会释放原来的资源,新建立连接,如果客户端关机不重启,服务器探测几次之后也知道对方挂了,会释放资源。
(6)延迟确认定时器
为了提高利用率,接收到报文,不立即回复ack,而是延时一段时间,将ack捎带在其他报文里。