TCP选项:SO_LINGER和TCP_DEFER_ACCEPT

来源:互联网 发布:h5游戏源码 ts 编辑:程序博客网 时间:2024/05/22 16:52

SO_LINGER选项:
typedef struct linger 

      u_short l_onoff;    //开关,零或者非零 
      u_short l_linger;   //优雅关闭最长时限 
} linger; 

当调用closesocket关闭套接字时,SO_LINGER将决定系统如何处理残存在套接字发送队列中的数据。处理方式无非两种:丢弃或者将数据继续发送至对端,优雅关闭连接。


l_onoffl_lingerclosesocket行为发送队列底层行为零忽略立即返回保持直至发送完成系统接管套接字并保证将数据发送至对端非零零立即返回立即放弃直接发送RST包,自身立即复位,不用经过2MSL状态。对端收到复位错误号非零非零阻塞直到l_linger时间超时或数据发送完成。(套接字必须设置为阻塞状态)在超时时间段内保持尝试发送,若超时则立即放弃超时则同第二种情况,若发送完成则皆大欢喜

1、设置 l_onoff为0,则该选项关闭,l_linger的值被忽略,等于内核缺省情况,close调用会立即返回给调用者,如果可能将会传输任何未发送的数据;
2、设置 l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
3、设置 l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直 到(a)所有数据发送完且被对方确认,之后进行正常的终止序列。

此种情况下,应用程序检查close的返回值是非常重要的,如果在数据发送完并被确认前时间到,close将返回EWOULDBLOCK错误且套接口发送缓冲区中的任何数据都丢失。close的成功返回仅告诉我们发送的数据(和FIN)已由对方TCP确认,它并不能告诉我们对方应用进程是否已读了数据。如果套接口设为非阻塞的,它将不等待close完成。


TIME_WAIT的作用是保证在主动关闭端口后,保证数据让对端收到,SO_LINGER选项可以避免端口的状态进入TIME_WAIT状态。
//使用SO_LINGER,close后不进入TIME_WAIT状态
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
setsockopt(serverSocket,SOL_SOCKET, SO_LINGER,(const char *) &linger,sizeof(linger));

当l_onoff非0是。l_linge也非0的时候,套接口在TIME_WAIT上将拖延一段时间,l_linger秒,而不再是2MSL的超时。


选项TCP_DEFER_ACCEPT:

例:

val = 5;
setsockopt(srv_socket->fd, SOL_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val)) ;    // val 的单位是秒,

如果打开这个功能,如果kernel 在 val 秒之内还没有收到数据,不会继续唤醒进程,而是直接丢弃连接。

服务器受到一个CONNECT请求后,操作系统不会Accept,也不会创建IO句柄。操作系统应该在若干秒,(但肯定远远大于上面设置的1s) 后,会释放相关的链接。但没有同时关闭相应的端口,所以客户端会一直以为处于链接状态。如果Connect后面马上有后续的发送数据,那么服务器会调用Accept接收这个链接端口。


0 0
原创粉丝点击