举例引入
对结了婚的夫妻来说,离婚的时候需要双方的同意。
四次挥手的过程
TCP/IP协议栈允许任何一方先发起断开过程
无论哪种情况,完成数据发送的一方会发起断开过程,这里以服务器一方发起断开过程为例。
- 首先,服务器一方的应用程序会调用Socket 库的close 程序。
- 然后,服务器的协议栈会生成包含断开信息的TCP 头部,具体来说就是将控制位中的FIN 比特设为1。
- 接下来,协议栈会委托IP 模块向客户端发送数据(图 ①)。同时,服务器的套接字中也会记录下断开操作的相关信息。
当客户端收到服务器发来的FIN 为1 的TCP 头部时,
- 首先 ,客户端的协议栈会将自己的套接字标记为进入断开操作状态。
- 然后,为了告知服务器已收到FIN 为1 的包,客户端会向服务器返回一个ACK 号(图 ②)。
- 接着,协议栈就可以等待应用程序来取数据了。过了一会儿,应用程序就会调用read 来读取数据A。这时,协议栈不会向应用程序传递数据A,而是会告知应用程序(浏览器)来自服务器的数据已经全部收到了。
根据规则,服务器返回请求之后,Web 通信操作就全部结束了,因此只要收到服务器返回的所有数据,客户端的操作也就随之结束了。
因此,客户端应用程序会调用close 来结束数据收发操作,这时客户端的协议栈也会和服务器一样,生成一个FIN 比特为1 的TCP 包,然后委托IP 模块发送给服务器(图③)。
一段时间之后,服务器就会返回ACK 号(图 ④)。到这里,客户端和服务器的通信就全部结束了。
为什么需要四次挥手才能断开连接,而不是三次?
在tcp连接握手时为何ACK是和SYN一起发送,但是在这里ACK却没有和FIN一起发送呢。原因是因为tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据。