欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网络编程-TCP的四次挥手

程序员文章站 2022-07-14 20:46:21
...

这篇文章,主要是整理一下 TCP 的四次挥手。在网络编程-从TCP三次握手说起介绍了关于TCP的三次握手。

四次挥手

四次挥手的流程在网上有很多图解,这里简略介绍一下,其最常见流程如下图所示,先来看看如何建立连接的:

网络编程-TCP的四次挥手
其大体流程如下:

1、客户端发其结束请求,发送seq=u,处于FIN-WAIT-1状态
2、服务端收到结束请求,发送应答ACK=u+1,处于CLOSE_WAIT状态
3、客户端收到u的应答后,处于FIN_WAIT_2状态,此时还可以接收来自服务端的数据
4、服务端没有数据要发送,也发送结束请求,seq=w,处于LAST_ACK状态
5、客户端又收到服务端的结束请求,客户端回应ACK,此时处于TIME_WAIT状态,确保ACK能够到达服务端;服务端收到客户端最终ACK,关闭连接。
6、2MSL时间结束后,无论服务端是否收到最终ACK,客户端完全结束连接。

四次挥手需要注意的问题?

TIME_WAIT的目的?

TIME_WAIT发生在TCP挥手的第四次挥手之后,这个状态的主要目的在于,客户端要确认最后一个ACK能够顺利的发送到服务端,当服务端没有收到ACK确认报文,那么一定是会重传这个FIN包。

TIME_WAIT为什么是2倍的MSL?

MSL(Maximum Segment Lifetime)是报文段的最大生存时间。

当第四次挥手发送完一个ACK报文的时候,它到达服务端的最大报文段传输时间为MSL,在极端情况下,刚好一个MSL的时候ACK报文段丢失,那么服务端就会重传一个FIN,那么它发送到客户端的时间就又是一个MSL,那么这种情况是极端的情况,也就是最大会有2倍的MSL时间间隔,当丢失后重传的FIN到达客户端的时候,那客户端就会重新设置为2倍的MSL,并且重传ACK。

可以借助netstat命令nc命令通过下面的方式观察到。在终端1监听8080端口:

终端1

nc -l 8080

终端2

nc 127.0.0.1 8080

终端3
通过netstat命令观察:

netstat -anpoc|grep :8080

然后在终端1按ctrl+c,终止连接,立刻观察终端3的结果:
网络编程-TCP的四次挥手
可以观察到,服务端当前处于TIME_WAIT,且有一个timewait的定时器,为1分钟。

close-wait得目的?

close-wait发生在第二次挥手后:当客户端第一次挥手,发送一个FIN报文,然后服务端不会立即发送FIN关闭连接的请求,而是发送一个ACK确认客户端关闭,这个时候客户端无法再向服务端发送数据,但是服务端会有一个close-wait,在这close-wait期间将未发送完的数据全部发送给客户端,当数据发送完了以后呢,就开始第三次挥手,发送一个FIN确认关闭连接。

什么是TCP半关闭

客户端在收到第一个FIN的ACK响应后,会进入FIN_WAIT2 状态时,此时服务器处于 CLOSE_WAIT状态,这种状态就称之为半关闭。

什么是TCP半关闭

如果一方已经关闭或异常终止连接,而另一方却不知道。 我们将这样的TCP连接称为半打开。

为什么要四次挥手?

这是因为TCP半关闭造成的。由于一个TCP连接是全双工的,在两个方向上都能传输数据,因此两个方向就需要单独关闭。所以这个流程是这样的:

发送FIN的一方就是主动关闭(客户端),而另一方则为被动关闭(服务器)。
当一方发送了FIN,则表示在这一方不再会有数据的发送。
其中当被动关闭方受到对方的FIN时,此时往往可能还有数据需要发送过去,因此无法立即发送FIN(也就是无法将FIN与ACK合并发送),
而是在等待自己的数据发送完毕后再单独发送FIN,因此整个过程需要四次交互。

TCP 工作流程

那么,一个TCP 正常的通讯流程,会包含建链(建立连接)、传输数据、拆链(关闭连接),如下图所示:

网络编程-TCP的四次挥手据上图所示,在进行 TCP 进行数据传输时,都不可避免的会经过这些阶段:

三次握手建立连接执行数据传输、双方读写四次挥手释放连接。

参考:
《Unix网络编程》
《TCP/IP协议详解》

网络编程-TCP的四次挥手
(微信公众号【程序猿编码】)

网络编程-TCP的四次挥手
(添加本人微信号,备注加群,进入程序猿编码交流群,领取学习资料,获取每日干货)

微信公众号【程序猿编码】,这里Linux c/c++ 、Go语言、数据结构与算法、网络编程相关知识,常用的程序员工具。还有汇聚精炼每日时政、民生、文化、娱乐新闻简报,即刻知晓天下事!

相关标签: UNIX网络编程