关键词搜索

源码搜索 ×
×

互联网协议 — TCP — TCP 连接(三次握手、四次挥手)

发布2023-03-12浏览4492次

详情内容

目录

三次握手、四次挥手

NOTE:要理解 TCP 的三次握手、四次挥手流程,首先需要对 TCP Header 有一个清晰的了解。

在这里插入图片描述

1、三次握手:建立 TCP 连接

  1. Client 调用 connect() 请求建立连接,发送 Segment(SYN=1,Seq=x)到 Server,Client 进入 SYN_SENT(已发送 SYN)状态,并等待 Server 响应;

  2. Server 调用 listen() 监听到连接请求,收到 SYN=1 后,理解了有连接请求到来。继续调用 accept() 接收连接请求,响应 Segment(SYN=1,ACK=x+1,Seq=y),Server 进入 SYN_RECV(接收到 SYN)状态;

  3. TCP Client 收到 ACK=x+1 后,理解了 Server 已经确认了自己的 ISN=x,然后进入 ESTABLISHED(已建立连接)状态,并响应 Segment(ACK=y+1)给 Server。Server 收到后 ACK=y+1 后,理解了 Client 已经确认了自己的 ISN=y,也进入到 ESTABLISHED(已建立连接)状态。

为什么需要三次握手?

TCP 连接建立的三次握手,主要有 2 个作用:

  1. 确认 C/S 双方的 TCP Segment 收、发功能正常。
  2. C/S 双方彼此确定对方的 ISN(Initial Sequence Number,初始序列号),例如:上述 TCP Client ISN=x,TCP Server 返回 ACK=x+1 表示已确定。同理,TCP Server ISN=y,TCP Client 返回 ACK=y+1 表示已确定。

之所以这么设计,主要有 2 个原因:

  1. TCP 将上层 Payload 当作字节流来处理,不会尝试理解 Payload 的含义,所以 TCP Seqments 需要保证准确的顺序切分和重组,否则 Payload 乱序。ISN 和 ACK 就用于保证顺序。

  2. ISN 对应 TCP Header 中的 Sequence Number(序列号)字段,长度为 32bit,取值范围为 0~2^32-1,并非无限大。所以 TCP C/S 会循环使用各自的 Seq,不会每次建立连接都从 0 开始,所以需要告知对方自己当前的 Seq Number。继而结合 ACK=n+1 来表达顺序。

而且,Linux Kernel 实现的 TCP 协议会以每 4μs 一次的频率进行 ISN+=1 操作,以此来避免 TCP 重连时,出现在同一条连接中存在 2 个及以上 Seq Number 相同的 Segment,从而导致顺序错乱。

2、数据传输

建立 TCP 连接之后,TCP C/S 双方都确认了对方的 ISN,开始通过 read() / write() 进行有序传输。

  1. TCP Client 调用 write(),发送 Segment(Seq=x+1,ACK=y+1)。
  2. TCP Server 接收 Segment(Seq=x+1,ACK=y+1)后,继续调用 read(),返回 Segment(ACK=x+2)。

3、四次挥手:断开 TCP 连接

  1. Client 调用 close(),发送 Segment(FIN=1,Seq=x+2,ACK=y+1),然后进入 FIN_WAIT_1(等待结束 1 阶段)状态。

  2. Server 接收到 FIN=1,理解了 Client 请求释放连接,然后进入 CLOSE_WAIT(等待关闭)状态,并返回 Segment(ACK=x+3)。

  3. Client 接收到 ACK=x+3 后,进入 FIN_WAIT_2(等待结束 2 阶段);不等 Client 返回 ACK,Server 继续调用 close(),发送 Segment(FIN=1,Seq=y+1),并进入 LAST_ACK(最后确认)状态。

  4. Client 接收到 FIN=1,理解了 Server 请求释放连接,并返回 Segment(ACK=y+2),进入 CLOSED(以释放状态)。Server 接收到 ACK=y+2 后,也进入 CLOSED 状态。

为什么需要四次挥手?

因为 TCP 连接是一种全双工的对等双向传输模式,双方很可能在同时收发数据。因此,当一方完成了所有的数据传输并想要关闭连接时,需要通知对方并等待对方的确认。

所以,TCP 释放连接需要四次挥手的主要原因是为了确保 C/S 双方都能够安全地关闭连接,并且可以保证数据的可靠传输。

  1. Client 发出第一个 FIN=1,表示 Client 已经完成了所有的数据传输。
  2. Server 发出第二个 FIN=1,表示 Server 也已经完成了所有的数据传输。

TCP 连接的状态机

Client 状态机

在这里插入图片描述

Server 状态机

在这里插入图片描述

TCP 连接的设计模式

实际上 TCP 协议标准并没有长连接、短连接的概念,只有 Keepalive 的概念。长连接、短连接只在于 TCP Application 的运行模式不同而已,本质是一种 Application 的设计模式。

在这里插入图片描述

短连接

TCP 短连接,即:C/S 双方在 connect() 建立连接之后,仅完成了一次 Read 和 Write 之后,即由任意一方 close() 发起关闭连接(通常由 Client 发起)。

短连接的优点是:管理简单,存在的连接都是有用的连接。

缺点是:假如 Server 处理请求连接过程非常耗时, 或者意外宕机, 此时 Client 会陷入长时间的等待状态。

长连接

TCP 长连接,即:C/S 双方在 connect() 建立连接之后,双方均不会主动关闭,在后续的 Read / Write 操作仍会继续使用这个连接。

相比于短连接,长连接的优点是:

  1. 较低的延时:无需多次进行三次握手、四次挥手。
  2. 较低的带宽占用:减少三次握手、四次挥手流量。
  3. 较少的系统资源占用:一个连接可用于多次读写,C/S 双方只需维护更少量的 Socket 资源。

缺点是

  1. 管理复杂,Server 需要甄别哪些连接是有效的,哪些连接没有在用是应该被释放的。否则会存在大量的无用连接,浪费资源。所以,Server 通常需要限制 Client 的最大连接数。

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载