可知客户端主动关闭socket时会进入Time_Wait状态
主动方-> FIN1包 -> 被动方
被动方-> ACK1包 -> 主动方
被动方-> FIN2包 -> 主动方
主动方-> ACK2包 -> 被动方
Time_Wait状态设计就是为了ACK2包能正确的发送给被动方,在python socket.close()后就交由操作系统负责这个连接Time_Wait状态的维护,所以如果短时间再次复用同一端口会出现端口被占用情况。为了解决这个问题有两种解决方案:
PS: server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)仅适用于服务器端
1. 不主动关闭套字节,让服务器主动关闭
可以在准备关闭时,故意sock.recv(1024)使得最后服务器因超时主动关闭,但局限性大,需要等待较长时间。其他方式无果,如setTimeout(xxx)或不执行close(),因为Python对于未正常关闭的套字节,会主动关闭并进入Time_Wait状态
2. 不进行正常关闭,主动发送异常状态
2.1 可以直接关闭相关进程来强制中断连接,这样状态会由操作系统直接进入CLOSED状态
2.2 使用RST替代FIN,使连接强制断开
typedef struct linger { // Windows Linger结构定义
u_short l_onoff;
u_short l_linger;
} LINGER, *PLINGER, *LPLINGER;
linger_struct = struct.pack('hh', 1, 0) # h对应windows上的u_short,延迟0s
sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, linger_struct)
sock.close()