背景:
测试socket程序,假设服务端监听5660端口,客户端去连接。客户端和服务端程序退出后,
服务端查看端口,有时会存在处于LAST_ACK状态的5660端口。导致服务端不能马上重开继续绑定5660端口,会绑定失败。
TCP连接断开流程图参照:
原因分析:
根据上图,服务端残留LAST_ACK状态的socket,是由于服务端调用close后,没有收到客户端返回的ACK确认包导致。
比较好的断开流程:
从客户端发起close(客户端可退出或者不退出都行。),服务端recv返回的长度会是0,此时服务端调用close,此时服务端不会残留sock。不影响重新绑定。
客户端虽然会有个端口处于TIME_WAIT,但此端口是连接服务端时随机分配的,不影响重新启动客户端再次进行连接。
其他流程:
1.客户端发起close,服务端收到后不进行close(忘记关闭)。此时客户端状态是FIN_WAIT_2,服务端状态是CLOSE_WAIT。之后无论客户端是否退出,两边会一直保持这个状态。
如果服务端程序退出了:客户端变成TIME_WAIT,服务端无残留。(不推荐,因为必须等服务端退出后,状态才会改变。)
2.服务端发起close,客户端收到后不进行close。此时服务端状态是FIN_WAIT_2,客户端状态是CLOSE_WAIT。之后无论服务端端是否退出,两边会一直保持这个状态。
如果客户端程序退出了,服务端会变成TIME_WAIT,有残留。服务端不能马上再次绑定原来5660端口。****(不推荐)
综合1.2:
一侧发起close,另一侧收到后不进行close。此时发起侧状态是FIN_WAIT_2,接收侧状态是CLOSE_WAIT。之后无论发起侧是否退出,两边会一直保持这个状态。
如果接收侧程序退出了:发起侧残留TIME_WAIT。