标签:
http://blog.chinaunix.net/uid-23207633-id-274317.html
之前在项目测试的时候,如果第三次握手发完裸ack(没有数据)之后不发送数据的时候,连接状态一直为SYN_RCV,而且服务端重传synack,当时很不解,后来看了下源码,才发现些端倪。当时测试的内核是2.6.18-194(centos5.5)。
我们看函数tcp_check_req
我们在用户层写socket程序时,可以通过setsockopt来设置TCP_DEFER_ACCEPT选项:
在内核空间会调用:
内核是通过函数inet_csk_reqsk_queue_prune进行重传synack:
那么TCP_DEFER_ACCEPT选项有什么好处呢,我们知道服务端处于监听时,客户端connect;服务端会收到syn包,并发送 synack;当客户端收到synack并发送裸ack时,服务端accept创建一个新的句柄,这是不支持TCP_DEFER_ACCEPT选项下的流 程。如果支持TCP_DEFER_ACCEPT,收到裸ack时,不会建立连接,操作系统不会Accept,也不会创建IO句柄。操作系统应该在若干秒 后,会释放相关的链接;但没有同时关闭相应的端口,所以客户端会一直以为处于链接状态,如果Connect后面马上有后续的发送数据,那么服务器会调用 Accept接收这个连接。
函数inet_csk_reqsk_queue_prune是通过tcp_synack_timer,是它在定时器中起作用的
关于定时器,在后续的分析中。
标签:
原文地址:http://www.cnblogs.com/mull/p/4478682.html