SO_LINGER 的设置

英文单词“linger”的意思为停留,我们可以通过设置套接字选项,来设置调用 close 或者 shutdown 关闭连接时的行为。


int setsockopt(int sockfd, int level, int optname, const void *optval,socklen_t optlen);

struct linger {
 int  l_onoff;    /* 0=off, nonzero=on */
 int  l_linger;    /* linger time, POSIX specifies units as seconds */
}

设置 linger 参数有几种可能:如果l_onoff为 0,那么关闭本选项。l_linger的值被忽略,这对应了默认行为,close 或 shutdown 立即返回。如果在套接字发送缓冲区中有数据残留,系统会将试着把这些数据发送出去。

如果l_onoff为非 0, 且l_linger值也为 0,那么调用 close 后,会立该发送一个 RST 标志给对端,该 TCP 连接将跳过四次挥手,也就跳过了 TIME_WAIT 状态,直接关闭。这种关闭的方式称为“强行关闭”。 在这种情况下,排队数据不会被发送,被动关闭方也不知道对端已经彻底断开。只有当被动关闭方正阻塞在recv()调用上时,接受到 RST 时,会立刻得到一个“connet reset by peer”的异常.可能为跨越 TIME_WAIT 状态提供了一个可能,不过是一个非常危险的行为,不值得提倡。

不要试图使用SO_LINGER设置套接字选项,跳过 TIME_WAIT;

 


struct linger so_linger;
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
setsockopt(s,SOL_SOCKET,SO_LINGER, &so_linger,sizeof(so_linger));

如果l_onoff为非 0, 且l_linger的值也非 0,那么调用 close 后,调用 close 的线程就将阻塞,直到数据被发送出去,或者设置的l_linger计时时间到。

 

总结:

TCP连接断开的时候调用closesocket函数,已经讨论过有优雅的断开和强制断开,那么如何设置断开连接的方式呢?是通过设置socket描述符一个linger结构体属性。

linger结构体数据结构如下:

struct linger

{


     int l_onoff;

     int l_linger;

};

有三种组合方式:

第一种

    l_onoff = 0;

    l_linger忽略

    这种方式下,就是在closesocket的时候立刻返回,底层会将未发送完的数据发送完成后再释放资源,也就

是优雅的退出。


第二种

    l_onoff非零

    l_linger = 0;

    这种方式下,在调用closesocket的时候同样会立刻返回,但不会发送未发送完成的数据,而是通过一个REST包强制的关闭socket描述符,也就是强制的退出。


第三种

    l_onoff非零

    l_linger > 0

    这种方式下,在调用closesocket的时候不会立刻返回,内核会延迟一段时间,这个时间就由l_linger得值来决定。如果超时时间到达之前,发送完未发送的数据(包括FIN包)并得到另一端的确认,closesocket会返回正确,socket描述符优雅性退出。否则,closesocket会直接返回错误值,未发送数据丢失,socket描述符被强制性退出。需要注意的时,如果socket描述符被设置为非堵塞型,则closesocket会直接返回值。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值