TCP三次握手四次挥手

TCP协议在OSI七层模型TCP/IP四层模型 中都属于传输层。

TCP 三次握手(建立连接)

目标 : 在客户端和服务器之间建立一个全双工的、可靠的 TCP 连接。所谓"全双工",意味着双方都可以同时向对方发送和接收数据。

核心概念:

  • SYN (Synchronize Sequence Numbers): 同步序列号。用于发起一个新连接,并协商初始序列号。

  • ACK (Acknowledgment): 确认。用于确认收到数据包,其值表示"期望收到的下一个字节的序列号"。

  • seq (Sequence Number): 序列号。TCP 为每个字节分配一个编号,用于保证数据的有序性和可靠性。

  • ack (Acknowledgment Number): 确认号。表示接收方期望从发送方收到的下一个字节的序列号,即 ack = 收到的seq + 数据长度 + 1(如果携带数据)。在握手阶段,数据长度为0,所以 ack = 收到的seq + 1。

握手过程

假设客户端(Client)想要连接服务器(Server)。

第一次握手 (SYN)

  • 发起方: 客户端

  • 动作: 客户端向服务器发送一个 TCP 数据包。

  • 标志位: SYN = 1

  • 序列号: seq = x (x 是客户端随机生成的初始序列号 - ISN)

  • 含义: "你好服务器,我想和你建立连接。我的初始序列号是 x。"

  • 此时客户端状态: 进入 SYN-SENT 状态。

第二次握手 (SYN + ACK)

  • 发起方: 服务器

  • 动作: 服务器收到客户端的 SYN 包后,如果同意连接,则会回复一个数据包。

  • 标志位: SYN = 1, ACK = 1

  • 序列号: seq = y (y 是服务器随机生成的初始序列号 - ISN)

  • 确认号: ack = x + 1

  • 含义: "你好客户端,我收到了你的连接请求(ACK)。我同意建立连接,我的初始序列号是 y。"

  • 此时服务器状态: 进入 SYN-RECEIVED 状态。

第三次握手 (ACK)

  • 发起方: 客户端

  • 动作: 客户端收到服务器的 SYN-ACK 包后,会再发送一个确认包。

  • 标志位: ACK = 1

  • 序列号: seq = x + 1 (因为第一次握手的 SYN 消耗了一个序列号)

  • 确认号: ack = y + 1

  • 含义: "好的服务器,我收到了你的确认。连接已经建立,我们可以开始传输数据了!"

  • 此时双方状态: 客户端和服务器都进入 ESTABLISHED 状态,可以开始数据传输。

为什么是三次,而不是两次?

这是一个经典问题,核心是为了防止已失效的连接请求报文突然又传送到服务器,从而产生错误。

情景模拟:

  • 客户端发送了一个 SYN 包(序列号=x)请求连接,但这个包在网络中滞留了(由于网络拥堵)。

  • 客户端超时未收到响应,于是重发了一个新的 SYN 包(序列号=y)并成功建立连接,传输数据后关闭了连接。

  • 此时,那个滞留在网络中的旧 SYN 包(序列号=x)终于到达了服务器。

  • 如果是两次握手 : 服务器收到这个旧 SYN 包,会误以为客户端又发起了新连接,于是回复 SYN-ACK 并进入连接就绪状态。服务器会一直等待客户端发送数据,但客户端早已关闭,根本不会理会这个连接。这就导致了服务器的资源被白白浪费。

  • 三次握手如何解决: 在三次握手的机制下,服务器回复 SYN-ACK 后,必须收到客户端的第三次 ACK 确认才会真正建立连接。在步骤3中,服务器发送了 SYN-ACK(ack=x+1),但客户端知道自己的当前序列号应该是 y 或更大,而不是 x,所以客户端会回复一个 RST 包来重置这个无效的连接,从而避免了服务器的资源浪费。

总结:三次握手确保了双方都确认了自己和对方的发送、接收能力是正常的,并且防止了失效的请求报文造成连接的误建立。

TCP 四次挥手(断开连接)

目标: 安全、可靠地关闭一个 TCP 连接。由于 TCP 连接是全双工的,每个方向都必须单独进行关闭。

核心概念
FIN (Finish) : 结束标志。表示发送方数据已发送完毕,要求释放连接。

挥手过程

假设客户端(Client)主动要求关闭连接。

第一次挥手 (FIN)

  • 发起方: 客户端

  • 动作: 客户端向服务器发送一个 TCP 数据包。

  • 标志位: FIN = 1

  • 序列号: seq = u (u 等于客户端已经传送过来的最后一个字节的序列号加1)

  • 含义: "你好服务器,我数据发完了,想要关闭从我这到你那边的连接(即客户端不再发送数据)。"

  • 此时客户端状态: 进入 FIN-WAIT-1 状态。

第二次挥手 (ACK)

  • 发起方: 服务器

  • 动作: 服务器收到 FIN 包后,立即发送一个确认包。

  • 标志位: ACK = 1

  • 序列号: seq = v

  • 确认号: ack = u + 1

  • 含义: "好的客户端,我收到你的关闭请求了。"

  • 此时状态

    • 客户端收到这个 ACK 后,进入 FIN-WAIT-2 状态。此时,从客户端到服务器的连接已经关闭,客户端不能再发送数据,但还可以接收数据。

    • 服务器进入 CLOSE-WAIT 状态。这个状态表示服务器可能还有数据需要发送给客户端。

第三次挥手 (FIN)

  • 发起方: 服务器

  • 动作: 当服务器也把所有剩余数据发送完毕后,它会发送一个 FIN 包。

  • 标志位: FIN = 1, ACK = 1 (通常会和ACK一起发送)

  • 序列号: seq = w (服务器在 CLOSE-WAIT 期间可能又发送了一些数据)

  • 确认号: ack = u + 1 (这里依然是确认客户端的第一个FIN)

  • 含义: "你好客户端,我这边数据也发完了,我也要关闭连接了(即服务器不再发送数据)。"

  • 此时服务器状态: 进入 LAST-ACK 状态。

第四次挥手 (ACK)

  • 发起方: 客户端

  • 动作: 客户端收到服务器的 FIN 包后,发送一个确认包。

  • 标志位: ACK = 1

  • 序列号: seq = u + 1 (因为第一次挥手的 FIN 消耗了一个序列号)

  • 确认号: ack = w + 1

  • 含义: "好的服务器,我收到你的关闭请求了。"

  • 此时状态

    • 客户端发送完 ACK 后,进入 TIME-WAIT 状态,等待 2MSL (Maximum Segment Lifetime,报文最大生存时间,通常为 2 分钟) 后,连接彻底关闭,进入 CLOSED 状态。

    • 服务器收到这个 ACK 后,连接立即关闭,进入 CLOSED 状态。

为什么是四次挥手?

因为 TCP 是全双工的,关闭连接需要双方各自关闭自己方向的通道。当客户端发送 FIN 时,只表示它不再发送数据,但还可以接收数据。服务器收到 FIN 后,先回复一个 ACK,这完成了半关闭。然后,服务器需要等待自己所有数据都发送完毕后,再发送自己的 FIN,客户端再回复 ACK,这才完成整个连接的关闭。因此,需要两个独立的 FIN 和 ACK 过程。

通信模式

主要有三种模式:单工、半双工 和 全双工

  1. 单工
  • 核心概念 : 数据传输是单向的,就像一条单行道。一方固定为发送者,另一方固定为接收者,角色不能改变。

  • 形象比喻

    • 广播电台(收音机): 电台只能发送信号,你的收音机只能接收信号,你无法通过收音机向电台发送声音。
  • 关键词: 只发不收 或 只收不发。

  1. 半双工
  • 核心概念 : 数据传输是双向 的,但不能同时进行。在同一时刻,只能有一方发送,另一方接收。它像一条单车道的桥,车流可以双向通行,但同一时间只能有一个方向的车辆通过。

  • 形象比喻

    • 对讲机: 你按下通话键说话时,无法听到对方的声音;松开按键收听时,你才能听到对方说话。双方不能同时讲话。
  • 关键词: 可以双向,但不能同时。

  1. 全双工
  • 核心概念 : 数据传输是双向 的,并且可以同时进行。通信双方都可以在发送数据的同时接收数据。它像一条宽阔的双向车道,两个方向的车辆可以同时通行,互不干扰。

  • 形象比喻

    • 电话通话: 你和朋友可以同时说话和听对方说话。
  • 关键词: 双向且同时。

四次挥手因为连接是全双工的 ,有两个独立的数据通道,所以关闭它需要四个步骤:

  • 客户端说:"我这边数据发完了(关闭客户端->服务器通道)。"

  • 服务器说:"好的,我知道了。"(但此时服务器->客户端通道可能还在传输数据)

  • 服务器数据发完后说:"我这边也发完了(关闭服务器->客户端通道)。"

  • 客户端说:"好的,再见。"

如果TCP是半双工的,那么断开连接可能只需要两次挥手就够了,因为同一时间只有一方能通信。

为什么客户端在 TIME-WAIT 状态必须等待 2MSL?

这是挥手过程中最复杂也最关键的一个设计,主要有两个目的:

  • 可靠地终止连接: 确保客户端的最后一个 ACK 能够到达服务器。如果这个 ACK 在网络中丢失,服务器在超时后会重发它的 FIN 包。客户端在 TIME-WAIT 状态下收到重发的 FIN,会重发 ACK 并重置 2MSL 计时器。如果没有 TIME-WAIT,客户端直接关闭,服务器将永远收不到 ACK,会一直处于 LAST-ACK 状态,无法正常关闭。

  • 让旧连接的报文在网络中消逝: 等待 2MSL 时间,可以确保本次连接产生的所有报文都已经从网络中消失,这样在建立下一个新的连接时,就不会收到旧的、失效的报文,从而避免数据混淆。

如果已经建立了连接,但客户端突然出现故障怎么办?

TCP 有一个保活机制 。服务器每收到一次客户端的数据,会重置一个保活计时器(通常设置为2小时)。如果计时器超时都未收到客户端任何数据,服务器会发送一个探测报文段,以后每隔75秒发送一次。若连续10个探测报文都没有响应,服务器就认为客户端出了故障,接着就关闭这个连接

相关推荐
YoungLime3 小时前
DVWA靶场之三:跨站请求伪造(CSRF)
网络·安全·web安全
TeleostNaCl3 小时前
如何在 Windows 上使用命令设置网卡的静态 IP 地址
网络·windows·经验分享·网络协议·tcp/ip·ip
Janspran3 小时前
监控系统1 - 项目框架 | 线程邮箱
网络·单片机·嵌入式硬件·硬件架构
XUE-52113144 小时前
组播实验-IGMP、IGMP Snooping及PIM-DM协议
运维·网络·网络协议·智能路由器
运维闲章印时光5 小时前
网络断网、环路、IP 冲突?VRRP+MSTP+DHCP 联动方案一次性解决
运维·服务器·开发语言·网络·php
国科安芯5 小时前
ASP3605电源芯片的性能优化与改进思路
网络·单片机·嵌入式硬件·安全·性能优化
liulilittle5 小时前
OPENPPP2 静态隧道链路迁移平滑(UDP/IP)
开发语言·网络·c++·网络协议·tcp/ip·udp·通信
Arlene5 小时前
IP 协议的相关特性
服务器·网络·tcp/ip
IvanCodes5 小时前
十六、Linux网络基础理论 - OSI模型、TCP/IP协议与IP地址详解
linux·网络·tcp/ip