我们在该文中分析了服务器和客户端之间的各种连接状态。
网络状态分析:
建立连接:
0、服务器端在调用accept后,且没有客户端发起连接时,服务器端处于LISTEN状态;
1、主动发起连接的一方,即客户端,发送SYN标志位后,变为SYN_SENT状态;
2、被动发起连接的一方,即服务器,收到SYN标志位后,并发送SYN+ACK,变为SYN_RCVD状态;
3、主动发起连接的一方,即客户端,收到SYN+ACK后,并发送ACK,变为ESTABLISHED状态;(connect函数返回)
4、被动发起连接的一方,即服务器,收到ACK标志位后,变为ESTABLISHED状态;(accept函数返回)
断开连接:
5、主动关闭连接的一方,一般为客户端(也可以是服务器),发送FIN标志位后,变为FIN_WAIT_1状态;(调用close)
6、被动关闭连接的一方,一般为服务器(也可以是客户端),收到FIN,并发送ACK后,变为CLOSE_WAIT状态;
7、主动关闭连接的一方,一般为客户端(也可以是服务器),收到ACK,变为FIN_WAIT_2状态;(处于半关闭)
8、被动关闭连接的一方,一般为服务器(也可以是客户端),发送FIN标志位后,变为LAST_ACK;(调用close)
9、主动关闭连接的一方,一般为客户端(也可以是服务器),收到FIN,并发送ACK后,变为TIME_WAIT状态;
10、被动关闭连接的一方,一般为服务器(也可以是客户端),收到ACK后,变为CLOSED状态;
11、主动关闭连接的一方,一般为客户端(也可以是服务器),再等待2MSL时长后变为CLOSED状态;
小结:从通讯流程图中可以看到,每个节点都对应一种状态的改变,其中,仅是发送端时,发送完状态变化;若既是接收端,又是发送端时,待接收并发送后,状态发生变化。
遇到客户端是FIN_WAIT_2,服务器端是CLOSE_WAIT的情形分析,卡在这个地方,两边的程序都无法继续执行了。
原因:客户端断开时,并没有关闭socket,就异常退出了。
此时,只能强制关闭程序。
解决方法:异常退出前,需要先close socket;
另外,注意客户端处于TIME_WAIT状态时,我们是可以继续在进行连接的,因为客户端的端口号并没有固定的指定。倘若是服务端处于TIME_WAIT时则不行。