【转】socket TCP_DEFER_ACCEPT

来源:互联网 发布:sql增量备份还原 编辑:程序博客网 时间:2024/06/14 00:03

http://blog.chinaunix.net/uid-20737871-id-1881239.html

想要提高TCP SERVER的性能(编程方面)
其中一个方法就是使用TCP_DEFER_ACCEPT来减少实际的ESTABLISHED连接数
当一个链接还没有实际传输数据时,使用此参数设置socket将会只产生SYN_RECV状态的链接
不得不说网上资料抄袭现象严重,而且残缺不全
首先这个参数定义的头文件就没有提到
还有timeout值的说明也有问题
甚至有些例子代码连前面的IPPROTO_TCP都写成SOL_SOCKET

TCP_DEFER_ACCEPT
此宏定义在netinet/tcp.h
具体用法

#include <netinet/tcp.h>
int timeout=1;
setsockopt( listen_fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, sizeof(int) )

具体解释
首先使用此选项设置监听端口的TCP属性
这样当监听端口接收到客户端的链接
不会直接丢给accept
而是在第一次接受到实际数据时才会建立真实链接

网上的几个误区
1.使用SOL_SOCKET
绝对的误人子弟,使用SOL_SOCKET进行设置的结果就是,调用函数无错误,但是实际效果是–没效果,任何连接上来就是ESTABLISHED
因为三次握手是TCP的属性
而不是SOCKET层面的额属性
所以要用IPPROTO_TCP

2.认为timeout就是连接上来几秒没数据就断开的时间
错!TCP链接并不会立刻断开
实际的超时时间是这么算的
当服务端一直没接受到数据后,会重发SYN/ACK给客户端
达到次数仍旧未接收到数据,才会开始timeout的计时
实际在CentOS 5.2下面大约是4分钟左右.

重发报文的次数在net.ipv4.tcp_synack_retries中定义
使用命令,我们可以看到CentOS默认的次数是5次

#sysctl -e net.ipv4.tcp_synack_retries
net.ipv4.tcp_synack_retries = 5

3.在setsockopt时使用参数0
这样做是没有意义的,
如果你设置timeout为0,你会发现链接上来的客户端立即变为ESTABLISHED
因为0的含义应该是
取消前面设置的TCP_DEFER_ACCEPT
直接确认最后一个ack上来的消息

原创粉丝点击