二:用电信号传输TCP/IP数据-4-断开连接

一、断开连接
收发数据结束的时间点应该是应用程序判断所有数据都已经发送完毕的时候,这时,数据发送完毕的一方会发起断开过程,但不同的应用程序会选择不同的断开时机。
在HTTP1.1中,浏览器向服务器发送请求消息,Web服务器返回响应消息之后,浏览器还可以继续发起下一个请求消息,如果接下来没有请求要发送了,客户端会发起断开过程。
协议栈在设计上允许任何一方先发起断开过程。

这里以服务器一方发起断开过程为例讲解。
1、服务器的应用程序会调用Socket库的close程序。
2、协议栈生成包含断开信息的TCP头部,具体来说就是将控制位中的FIN比特设为1。
3、协议栈委托IP模块向客户端发送数据,同时服务器的套接字中也会记下断开操作的相关信息。
4、客户端收到服务器发来的FIN为1的TCP头部时,客户端协议栈会将自己的套接字标记为进入断开状态。
5、客户端向服务器返回1个ACK号,告知服务器已收到FIN为1的包。

应用程序调用read来读取数据时,协议栈不会向应用程序传递数据(如有还是会传),而是会告知应用程序来自服务器的数据已经全部收到。
此时,应用程序会调用close来结束收发操作,后面的过程和服务器上的类似。

二、删除套接字
和服务器通信结束后,用来通信的套接字也就不再使用了,这时就可以删除这个套接字,不过不是立即删除,而是要等待一段时间。
等待的原因时为了防止误操作,误操作的情况有很多,讲一个简单的例子。
客户端发起断开的流程如下:
1)客户端发送PIN
2)服务器返回ACK号
3)服务器发送FIN
4)客户端返回ACK号
如果上面4个步骤里最后客户端返回的ACK号丢失了,会发生什么呢?
服务器没有收到ACK号,又重发一次FIN,如果客户端没有等待一段时间而是在发送完ACK号之后立即删除了套接字,那么套接字中的控制信息跟着消失,占用的端口号也被立即释放出来,如果凑巧另一个应用程序创建的新套接字又被分配了这个端口,那么服务器重发的FIN到达后就会进入到这个新套接字,新套接字就开始错误地执行断开操作了。
所以,有必要等待一段时间再删除套接字。

至于等待多长时间,这个机制类似于包的重传。网络包丢失之后会进行重传,一般持续几分钟,如果依然无效则停止重传。所以这个时间没有明确的规定,一般时几分钟。

收据收发流程整体回顾:

posted @ 2023-05-23 10:31  GPL-技术沉思录  阅读(8)  评论(0编辑  收藏  举报