linger选项打开时:
被动关闭的一端,检查socket的读状态会返回0,但可读的数据长度为0。可以依据它来快速关闭半关闭的socket连接。
closesocket也不是真正意义上的阻塞,它其实是指是否等待关闭,受套接字选项SO_LINGER和SO_DONTLINGER的影响。
若SO_DONTLINGER或SO_LINGER的间隔=0时,closesocket就是非等待关闭的,但是当SO_LINGER的间隔>0时,closesoket就是等待关闭的,直到剩余数据都发送完毕或直到超时才退出。
(但是这个地方只有对于阻塞的套接口才有用,如果是非阻塞的套接口,它会立即返回并且指示错误WOULDBLOCK)。
TCP连接断开场景测试:
case:客户端运行在Linux环境下,服务器运行在Windows环境下,当客户端主动断开连接的同时,如果还有数据发送。会导致服务器端处于异常状态(检查socket可读状态为0,可读数据有,但recv返回失败),无法恢复。
(已解决)FIONREAD选项在linux环境下不可用。使用socket可读状态和recv返回值来判定socket是否为半关闭连接。
case:服务器端运行在Linux环境下,客户端运行在Windows环境下,双方对发通信数据,当客户端主动关闭连接时,服务器端程序会挂掉。
(已解决)send系统函数设置选项MSG_NOSIGNAL。
(linux环境下,当连接断开时发送数据,send()返回失败,还会向系统发送一个异常消息,如果不作处理,系统会出BrokePipe,程序会退出,这对于服务器提供稳定的服务将造成巨大的灾难。为此,send()函数的最后一个参数可以设MSG_NOSIGNAL,禁止send()函数向系统发送异常消息。)
客户端在Linux环境下,服务器端在Windows环境下:
(1)服务器端主动断开
服务器端:(下列第一种情况会对关闭过程有影响)
有数据通信时:
直接发送Reset消息,linger设置选项和阻塞选项无效。
无数据通信时:
(shutdown(*sock, 2);)关闭时:
linger打开时:直接发送Reset消息
阻塞选项对断开过程无影响。
linger关闭时:执行文明关闭过程。
阻塞选项对断开过程无影响。
(shutdown(*sock, 2);)打开时:
执行文明关闭过程。
阻塞模式和linger选项的设置对关闭过程没有影响。
客户机端:(linger选项会对关闭过程有影响)
有数据通信时:
直接发送Reset消息,linger设置选项和阻塞选项无效。
无数据通信时:
linger选项打开时:
(shutdown(*sock, 2);)关闭时:第三次握手时发送一个Reset消息。
阻塞选项对断开过程无影响。
(shutdown(*sock, 2);)打开时:在执行完文明关闭过程后,客户端发送一个Reset消息。
阻塞选项对断开过程无影响。
linger选项关闭时,执行文明关闭过程。
(shutdown(*sock, 2);)选项和BLOCK选项的设置对关闭过程没有影响。
(2)客户端主动断开
客户机端:
(shutdown(*sock, 2);)关闭时:
有数据通信时:
直接发送Reset消息。
linger选项和阻塞选项的设置对断开过程无影响。
没有数据通信时:
linger关闭时,执行文明关闭过程。
linger打开时,直接发送Reset消息。(阻塞方式无影响)
(shutdown(*sock, 2);)打开时:
有数据通信时:
先发送FIN&ACK消息,收到ACK,发送Reset&ACK和Reset消息。(偶尔)
阻塞选项和linger选项的设置对断开过程没有影响。
没有数据通信时:
阻塞选项对关闭行为没有影响。
linger选项关闭时:执行文明关闭行为。
linger选项打开时:先发送FIN&ACK消息,收到ACK,发送Reset&ACK和Reset消息。
服务器端:
linger选项、(shutdown(*sock, 2);)选项和阻塞选项的设置对关闭过程没有影响。
客户端在windows环境下,服务器端在Linux环境下:
(1)服务器端主动断开
服务器端:
(shutdown(*sock, 2);)关闭时:
无数据通信时:
linger打开时:直接发送Reset消息
阻塞选项对断开过程无影响。
linger关闭时:执行文明关闭过程。
阻塞选项对断开过程无影响。
有数据通信时:
直接发送Reset消息。
(shutdown(*sock, 2);)打开时:
无数据通信时:
当设置为阻塞模式时:
linger打开时:先发送FIN&ACK消息,再发送Reset消息。(ACK消息不一定能收到)
linger关闭时:执行文明关闭过程。
当设置为非阻塞模式时:
linger打开时:先发送FIN&ACK消息,收到ACK消息后,发送Reset消息。
linger关闭时:执行文明关闭过程。
有数据通信时:
先发送FIN&ACK消息,再发送Reset消息。
客户机端:
无数据通信时:
(shutdown(*sock, 2);)打开时:
BLOCK选项对断开过程没有影响。
linger选项对断开过程没有影响。
(shutdown(*sock, 2);)关闭时:
BLOCK选项对断开过程没有影响。
linger选项打开时,关闭过程第三次握手客户端会发送一个Reset消息。
有数据通信时:
设置选项对断开行为没有影响。
(2)客户端主动断开
(当服务器端的linger选项关闭时,会导致连接很长时间内不能建立,无论客户端的linger选项如何)
客户机端:
无通信数据时:
(shutdown(*sock, 2);)关闭时:
linger打开时:
客户端直接发送Reset消息。
与阻塞选项的设置无关。
linger关闭时:
执行文明关闭过程,四次握手之后会收到服务器端的Reset消息。
与阻塞选项的设置无关。
(shutdown(*sock, 2);)打开时:
执行文明关闭过程,四次握手之后会收到服务器端的Reset消息。
阻塞模式和linger选项对断开过程没有影响。
有通信数据时:
直接发送Reset消息。
服务器端:
linger选项关闭会导致连接很长时间内不能恢复。
linger选项打开会在四次握手之后(如果存在)发送Reset消息。
BLOCK选项对断开过程没有影响。
(shutdown(*sock, 2);)关闭时,服务器端发送完ACK消息后会直接发送Reset消息。