断开连接操作:
断开连接操作一般由数据发送的一方发起断开的过程,可能是服务器,也可能是客户端。这里以服务器为例,服务器会首先调用Socket库中的close程序,然后服务器的协议栈就会生成有关断开连接的TCP头部,具体是将TCP头部中控制位的FIN比特值设置为1。接下来就是将这段信息发送给客户端,客户端接收到后返回ACK值表示接收到了。这些操作完成后协议栈就可以等待应用程序来读取加载的数据了。当数据都接收完毕,协议栈会告知应用程序信息收发完毕了,该断开连接了,应用程序得知后会调用Socket库中的close方法来结束收发操作,此时协议栈会和之前服务器的协议栈一样发送FIN为1的通知,服务器接收到后返回ACK表示接收到,此时通信结束。
删除套接字:
通信结束后,套接字不会立马删除,而是会等待一段时间,因为套接字中包含有连接相关信息,假设是由客户端发起断开连接操作,那么就是客户端发送FIN,服务器回复ACK,服务器发送FIN,这是客户端还是处于连接状态,客户端会向服务器发送最后的ACK表示接收到,然后删除套接字。这时好巧不巧,最后一次发送的ACK包丢失了,服务器在那等半天:“卧槽,说好结束了呢,咋每个回应”。到了最大等待时间后,服务器端重新发送FIN给原本端口号的应用程序,而占有原本端口号的套接字无了,这时又好巧不巧,有个新的应用程序创建了套接字,端口号正好是这个端口号,刚上号就收到了一个断开连接的FIN,好了兄弟们,下号。然后连接刚建立就断了,后台的人一脸懵逼。这就是删除套接字的问题所在。