TCP三次握手四次挥手笔记

TCP是一个面向连接的协议,通信双方传输数据之前,必须建立连接。TCP建立连接和断开连接的策略,可以分不同层次的掌握,这里大致分4层。

一、通俗化的描述

建立TCP连接
服务器A和服务器B通信,建立连接比较好理解的比喻:
服务器A:你好服务器B,我是服务器A。
服务器B:你好服务器A,我是服务器B。
服务器A:服务器B,你好。

断开TCP连接
设定服务器A是主动结束方
服务器A:你好, 我的数据发送完毕了,我要进入准备断开的状态了。(此时它虽然不再发送数据了,但是可以接受数据)
服务器B:我知道了,我还没有发送完毕的,你等着吧。
服务器B:我也发送完毕了,可以断开连接了。(此时它也进入准备断开的状态)
服务器A:好的,那断开吧。

二、知道大致策略

建立TCP连接
所谓三次握手,是指建立一个TCP连接时,发送端和接收端总共要发送3个数据包。
0、发送端首先发送一个带SYN标志的数据包(第一个数据包)给接收方。
1、接收端收到后,回传一个带有SYN/ACK标志的数据包(第二个数据包)以示传达确认信息。
2、发送端再回传一个带ACK标志的数据包(第三个数据包),代表”握手”结束。
示意图如下:

断开TCP连接
所谓的四次挥手,是指断开一个TCP连接时,发送端和接收端总共要发送4个数据包。发送端和接收方都可以是主动断开方。一般是发送方主动断开。
0、发送方发送一个FIN,用来关闭发送方的连接。
1、接收方收到FIN,回传一个ACK。
2、接收方关闭与发送方的连接,发送一个FIN。
3、发送方回传ACK。
示意图如下:

三、熟悉TCP的报文格式, 深入理解数据包含义

TCP包封装在IP包中的格式

TCP包首部格式如下图所示

大致弄明白TCP首部格式后,我们重点关注其中控制位中的3个Flag
SYN 为1时表示希望建立连接
ACK 为1表示确认应答字段变为有效
FIN 为1表示请求断开连接

清楚这个之后,我们很容易就明白了建立连接和断开连接过程中发送数据包的目的和含义

完整的过程如下图:

四、TCP建连和断连过程中客户端和服务器状态

TCP建连和断连过程中,客户端和服务器会经过多个状态的变化,变化过程如下图:

0、客户端从连接到关闭状态变化
CLOSED -> SYN_SENT -> ESTABLISHED -> FIN_WAIT_1 -> FIN_WAIT_2 -> TIME_WAIT -> CLOSED

1、服务端从连接到关闭状态变化
CLOSED -> LISTEN -> SYN_RCVD -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED

2、比较重要的状态一:TIME_WAIT
当客户端执行一个主动关闭,并发送最后一个带ACK标志的数据包,客户端进入TIME_WAIT状态,这个状态停留时间为2MSL。

维持这个状态主要有两个原因:
一、客户端4次挥手发送的最后一个带ACK的数据包可能丢失,维护这个状态可以重发。
二、一个TCP连接关闭后,在2MSL等待期间,这个连接使用的IP和端口不能再被使用,否则上一个连接延迟的数据包可能被误用。

注:MSL(Maximum Segment Lifetime)为一个报文段在网络上生存的最大时间。现实中这个时间大小通常是30s, 1min, 2min。

3、比较重要的状态二: CLOSE_WAIT
服务端被动关闭会进入这个状态。

关于TIME_WAIT和CLOSE_WAIT,可参考这里

4、思考
为啥通常会出现大量TIME_WAIT, 是在客户端出现,还是服务端出现?
为啥通常会出现大量CLOSE_WAIT, 是在客户端出现,还是服务端出现?

五、为什么需要3次握手4次挥手

0、为什么需要3次握手。4次及以上是没必要,主要讨论2次的情况

原因一:
如果通过2次握手建立连接,那么下面这种特殊情况会造成资源浪费。
服务端收到客户端已失效的请求报文后,回应一个数据包,建立的连接,这个连接是没有意义的,因为客户部此时不会在通过这个连接传输数据包。

备注:失效请求报文指:客户端的一个连接请求数据包并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达服务端)

原因二:
经过3次,才能确保客户端和服务端都可以发包和收包。

备注:这是跟B站的同行交流得知的,挺有道理。

1、为什么需要4次挥手。主要讨论3次的情况(第二次ACK和第三次的FIN一起发送)
一个TCP连接是全双工(数据包在两个方向上能同时传递)。因此每一分都必须进行单独关闭。服务端收到了客户端的FIN包,表示收到客户端的断开请求,客户端收到服务端回应的ACK包,才会真正断开连接(此时客户端不发送数据包,但能接收数据包)。如果服务端在回应客户端的ACK中同时带上了FIN标示,就表明服务端也同时请求断开连接(不发送数据),这就有点强迫的感觉,一方要断了,另一方也必须断。这样就不能实现可靠的连接关闭了。因为客户端断了连接,还能收到数据包,服务端可能还有数据包需要传输,不一样想断。

六、最后

优兔上有一个视频介绍的异常清楚,传送门TCP connection walkthrough | Networking tutorial

参考:
《图解TCP/IP》
《TCP/IP详解(卷一协议)》
《图解HTTP》
TCP为什么需要3次握手与4次挥手
tcp建立连接为什么需要三次握手

发表评论

电子邮件地址不会被公开。 必填项已用*标注