SO_LINGER选项用来改变此缺省设置。使用如下结构:
struct linger {
int l_onoff; /* 0 = off, nozero = on */
int l_linger; /* linger time */
};
有下列三种情况:
1、设置 l_onoff为0,则该选项关闭,l_linger的值被忽略,等于内核缺省情况,如果有数据残留在socket发送缓冲区中则系统将继续发送这些数据给对方,等待被确认,然后返回。最终关闭按照四次握手time-wait进行关闭。也就是所有数据都发送完成以后,才会发送fin,这种默认方式最保险、无数据丢失。如果想异常关闭那么就使用下面两种方式,也就是中途发送rst,而不是fin、四次握手
2、设置 l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
3、设置 l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。如果socket发送缓冲区中仍残留数据,进程进入睡眠,内核进入定时状态去尽量去发送这些数据。
在超时之前,如果所有数据都发送完且被对方确认,内核用正常的FIN|ACK|FIN|ACK四个分组来关闭该连接,close()成功返回。
如果超时之时,数据仍然未能成功发送及被确认,用上述a方式来关闭此连接。close()返回EWOULDBLOCK。