socket编程中主动关闭VS被动关闭
tcp中server,client都可能是主动关闭方或者被动关闭方,现阐述下两者之间的关系:
客户端(client) 服务器(server)
close() Fin x -> 读通道关闭(close_wait)
写通道关闭 <- Ack x+1
读通道关闭(time_wait) <- Fin y close()
ack y+1 -> 写通道关闭
2x msl closed
closed
1、 客户端是调用函数close(),这时,客户端会发送一个FIN给服务器。
2、 服务器收到FIN,关闭套接字读通道,并将自己状态设置为CLOSE_WAIT(表示被动关闭),
并返回一个ACK给客户端。
3、 客户端收到ACK,关闭套接字写通道
接下来,服务器会调用close():
1、 服务器close(),发送一个FIN到客户端。
2、 客户端收到FIN,关闭读通道,并将自己状态设置成TIME_WAIT,发送一个ACK给服务器。
3、 服务器收到ACK,关闭写通道,并将自己状态设置为CLOSE。
4、 客户端等待两个最大数据传输时间,然后将自己状态设置成CLOSED。
有了上面的背景知识,对于我们系统线上一个case分析就很简单了!
首先是主动关闭日志很多,后来是被动关闭的日志
由于server端发现了大量闲置的没有Io的socket连接,有监听器在监听是否存在闲置的socket连接,就释放并关闭这些连接,time_wait就出现了,这个时候应用方客户端重启应用,释放了资源包括一些客户端连接,这个时候close_wait出现了,正好是以上日志所反映的
同时time_wait状态的连接是不会释放内核资源,所以服务端不要轻易close!
推荐阅读