SO_LINGER
选项用于调整close
行为,可以设置为强制关闭socket
以回收资源
缺省close
的行为是,如果有数据残留在socket
发送缓冲区中则系统将继续发送这些数据给对方,等待被确认,然后返回。
利用此选项,可以将此缺省行为设置为以下两种:
- 立即关闭该连接,通过发送 RST 分组(而不是用正常的 FIN|ACK|FIN|ACK 四个分组)来关闭该连接。至于发送缓冲区中如果有未发送完的数据,则丢弃。主动关闭一方的 TCP 状态则跳过 TIMEWAIT,直接进入 CLOSED。网上很多人想利用这一点来解决服务器上出现大量的 TIMEWAIT 状态的 socket 的问题,但是,这并不是一个好主意,这种关闭方式的用途并不在这儿,实际用途在于服务器在应用层的需求
- 将连接的关闭设置一个超时。如果 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 == 0
,close
用上述方式 1
关闭连接l_onoff != 0 && l_linger != 0
,close
用上述方式 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 | 非零 | 优雅 | 是 |