0%

tcp 选项 SO_LINGER

SO_LINGER选项用于调整close行为,可以设置为强制关闭socket以回收资源

缺省close的行为是,如果有数据残留在socket发送缓冲区中则系统将继续发送这些数据给对方,等待被确认,然后返回。

利用此选项,可以将此缺省行为设置为以下两种:

  1. 立即关闭该连接,通过发送 RST 分组(而不是用正常的 FIN|ACK|FIN|ACK 四个分组)来关闭该连接。至于发送缓冲区中如果有未发送完的数据,则丢弃。主动关闭一方的 TCP 状态则跳过 TIMEWAIT,直接进入 CLOSED。网上很多人想利用这一点来解决服务器上出现大量的 TIMEWAIT 状态的 socket 的问题,但是,这并不是一个好主意,这种关闭方式的用途并不在这儿,实际用途在于服务器在应用层的需求
  2. 将连接的关闭设置一个超时。如果 socket 发送缓冲区中仍残留数据,进程进入睡眠,内核进入定时状态去尽量去发送这些数据。在超时之前,如果所有数据都发送完且被对方确认,内核用正常的 FIN|ACK|FIN|ACK 四个分组来关闭该连接,close成功返回。如果超时之时,数据仍然未能成功发送及被确认,用上述方式 1来关闭此连接。close返回EWOULDBLOCK

使用如下结构

struct linger {
     int l_onoff; /* 0 = off, nozero = on */
     int l_linger; /* linger time */
};
  • l_onoff == 0,则该选项关闭,l_linger的值被忽略,close用上述缺省方式关闭连接
  • l_onoff != 0 && l_linger == 0close用上述方式 1关闭连接
  • l_onoff != 0 && l_linger != 0close用上述方式 2关闭连接
int z; /* Status code */
int s;       /* Socket s */
struct linger so_linger;
...
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
z = setsockopt(s,
    SOL_SOCKET,
    SO_LINGER,
    &so_linger,
    sizeof so_linger);
if ( z )
    perror("setsockopt(2)");
close(s); /* Abort connection */

选项 间隔 关闭方式 等待关闭与否
SO_DONTLINGER 不关心 优雅
SO_LINGER 强制
SO_LINGER 非零 优雅

Ref

  1. setsockopt :SO_LINGER 选项设置
  2. Socket 选项系列之 SO_LINGER