当前位置: 首页 > article >正文

“三次握手”与“四次挥手”:TCP传输控制协议连接过程

目录

什么是TCP协议

“三次握手”建立连接

“四次挥手”断开连接

“三次握手”和“四次挥手”的反思

总结


什么是TCP协议

想象一下,你和远方的朋友要进行一场电话交流,但这通电话不仅仅是随便聊聊,而是要传递一封重要的信件。为了确保这封信能够完整、准确地传递,你们制定了一系列规则,比如谁先说、如何确认对方听到了、如果听不清怎么办。这些规则,就像是TCP协议(Transmission Control Protocol,传输控制协议)在计算机网络中的作用。

TCP的基本概念

TCP 是一种面向连接的、可靠的基于流的传输协议,运行在传输层。它主要用于确保数据能完整、准确地从一台计算机传输到另一台计算机,即使网络环境并不稳定。

简单理解:

  • 面向连接:就像打电话一样,TCP 需要在数据传输前先建立一条稳定的通信线路(连接)。
  • 可靠传输:TCP 确保数据不会丢失、不会重复、不会乱序,就像你确保信件被完整送达。
  • 流式传输:TCP 以数据流的方式传输数据,而不是像快递那样一次性把所有内容打包。

“三次握手”建立连接

在TCP通信开始前,必须先建立连接,这就像是打电话时要先拨号、等待对方接听,然后确认对方能听清楚。

当客户端(Client)和服务器(Server)建立TCP连接时,会经历“三次握手”过程。其目的是:

确保客户端和服务器都具备发送和接收能力。

协商初始序列号(ISN,Initial Sequence Number),防止数据包混乱。

假设客户端A想要与服务器B建立连接:

第一次握手(SYN)

  • 客户端A发送一个 SYN(同步)数据包给服务器B,请求建立连接。
  • 该数据包包含:
    • SYN=1(表示请求建立连接)
    • 初始序列号 ISN(A)(用于数据传输的编号,防止乱序)
  • 这时,客户端A进入 SYN_SENT(同步已发送) 状态。

第二次握手(SYN-ACK)

  • 服务器B收到SYN请求后,回应一个 SYN-ACK(同步-确认)数据包。
  • 该数据包包含:
    • SYN=1(表示服务器同意建立连接)
    • ACK=1(表示确认收到客户端的SYN请求)
    • 服务器的初始序列号 ISN(B)
    • 确认号 ACK=ISN(A)+1(表示已收到客户端的SYN)
  • 服务器B进入 SYN_RECV(同步已收到) 状态。

第三次握手(ACK)

  • 客户端A收到服务器B的SYN-ACK后,发送一个 ACK(确认)数据包。
  • 该数据包包含:
    • ACK=1(确认连接)
    • 序列号 = ISN(A)+1
    • 确认号 ACK=ISN(B)+1(表示已收到服务器的SYN)
  • 服务器B收到ACK后,连接正式建立,双方进入 ESTABLISHED(已建立) 状态。

至此,TCP连接成功建立,双方可以开始数据传输。

TCP如何保证数据可靠传输?

TCP 采用了多个机制来确保数据不会丢失、不会重复、不会乱序。

数据包的编号与确认

每个TCP数据包都会有一个序列号(Sequence Number),而接收方会发送确认号(Acknowledgment Number) 来确认收到的数据。

例如:客户端发送 Seq=1000 的数据包,服务器收到后,会回复 Ack=1001,表示已成功接收。

如果服务器没有收到这个数据包,它不会发送 Ack=1001,这样客户端就知道数据丢失了,需要重新发送。

超时重传

如果客户端发送了数据包,但一直没有收到确认(ACK),就会在一定时间后重发数据,直到对方确认收到。

  • 这类似于寄快递时,如果包裹长时间未送达,快递员可能会重新派送。

流量控制

TCP 允许接收方通过滑动窗口机制控制数据发送速度,避免发送方数据过快而接收方处理不过来。

例如:如果服务器处理能力有限,它可以告诉客户端“慢点发,我忙不过来了”,客户端就会降低发送速度。

拥塞控制

当网络拥堵时,TCP 会自动降低发送速率,以防止网络进一步恶化。

这就像高速公路上遇到堵车时,大家会自动放慢速度,避免发生更严重的交通事故。

“四次挥手”断开连接

当通信结束时,TCP使用“四次挥手”来关闭连接。其目的是:

  1. 确保双方都完成数据传输后,安全地关闭连接。
  2. 防止数据丢失,确保所有数据包都被正确接收。

假设客户端A想要断开与服务器B的TCP连接:

第一次挥手(FIN)

  • 客户端A发送 FIN(终止)数据包,表示“我不想再发送数据了”。
  • 该数据包包含:
    • FIN=1(请求关闭连接)
    • 序列号 seq=U(U是当前数据序列号)
  • 客户端A进入 FIN_WAIT_1(终止等待1) 状态。

第二次挥手(ACK)

  • 服务器B收到FIN后,发送一个 ACK(确认)数据包。
  • 该数据包包含:
    • ACK=1(确认关闭请求)
    • 序列号 = V
    • 确认号 ACK=U+1(确认收到FIN)
  • 服务器B进入 CLOSE_WAIT(关闭等待) 状态,等待完成剩余的数据传输。
  • 客户端A进入 FIN_WAIT_2(终止等待2) 状态,等待服务器B发送FIN。

第三次挥手(FIN)

  • 服务器B数据传输完成后,主动发送 FIN(终止)数据包,表示“我也不想再发送数据了”。
  • 该数据包包含:
    • FIN=1(请求关闭)
    • 序列号 seq=W
  • 服务器B进入 LAST_ACK(最后确认) 状态,等待客户端的最后ACK。

第四次挥手(ACK)

  • 客户端A收到服务器B的FIN后,发送一个 ACK(确认)数据包,表示“确认关闭”。
  • 该数据包包含:
    • ACK=1(确认关闭请求)
    • 序列号 = X
    • 确认号 ACK=W+1(确认收到FIN)
  • 服务器B收到ACK后,立即进入 CLOSED(关闭) 状态,释放连接。
  • 客户端A等待 TIME_WAIT(通常是2倍的MSL时间,默认240秒)后,最终进入 CLOSED 状态,连接彻底关闭。

至此,TCP连接完全关闭,确保所有数据包已经被正确处理。

“三次握手”和“四次挥手”的反思

为什么 TCP 需要三次握手,而不是两次?

两次握手可能会导致已失效的 SYN 报文被服务器误认为是新的连接,从而建立了一个无效连接。而三次握手可以确保双方都明确对方的接收和发送能力。例如,客户端发出的 SYN 因为网络问题被延迟,服务器收到后认为是新的连接请求并建立连接,但客户端并不知情,导致连接状态不同步。
三次握手能够确保:

客户端确认服务器的 接收能力

服务器确认客户端的 接收能力

双方都确认了彼此的 发送和接收能力,确保连接有效。

为什么 TCP 需要四次挥手,而不是三次?
因为 TCP 是全双工通信,数据的发送和接收是独立的,一方发出 FIN 只表示它不再发送数据,但仍然可以接收数据,所以另一方要单独再发送 FIN 以表示自己也不再发送数据,这就导致了四次挥手。

为什么A在TIME-WAIT状态必须等待2MSL的时间
MSL最长报文段寿命Maximum Segment Lifetime,MSL=2
这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,B超时重传FIN+ACK报文段,而A能在2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,重新启动2MSL计时器,最后A和B都进入到CLOSED状态,若A在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到B重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则B无法正常进入到CLOSED状态。
总结:

  • 确保 B 已经收到 A 的最后一个 ACK,若 B 没收到,会重发 FIN,A 需要有时间处理。
  • 防止历史连接中的旧报文在网络中滞留,影响后续新的连接。

总结

三次握手(TCP 连接建立)

A -> B(SYN):A 发送 SYN 报文,表示请求建立连接,进入 SYN-SENT 状态。

B -> A(SYN-ACK):B 收到 SYN 后,发送 SYN-ACK 报文,表示同意建立连接,进入 SYN-RECEIVED 状态。

A -> B(ACK):A 收到 SYN-ACK 后,发送 ACK 报文,B 进入 ESTABLISHED 状态,A 也进入 ESTABLISHED 状态,连接建立完成。

四次挥手(TCP 连接释放)

A -> B(FIN):A 发送 FIN 报文,表示不再发送数据,进入 FIN-WAIT-1 状态。

B -> A(ACK):B 收到 FIN 后,发送 ACK,表示确认,进入 CLOSE-WAIT 状态;A 收到 ACK 后,进入 FIN-WAIT-2 状态。

B -> A(FIN):B 处理完剩余数据后,发送 FIN 报文,进入 LAST-ACK 状态。

A -> B(ACK):A 收到 FIN 后,发送 ACK 报文,进入 TIME-WAIT 状态,等待 2MSL;B 收到 ACK 后,进入 CLOSED 状态。

A 进入 CLOSED 状态:等待计时器 2MSL 结束后,A 进入 CLOSED 状态,连接彻底关闭。


http://www.kler.cn/a/552923.html

相关文章:

  • 在Kubernetes上部署DeepSeek-R1进行高效AI推理
  • C#```
  • 一文读懂Docker之Docker Compose
  • 论文笔记-WSDM2024-LLMRec
  • 02.19 构造函数
  • MYSQL数据库特殊查询-INFORMATION_SCHEMA
  • 鉴源实验室·智能网联汽车协议数据传输安全分析与防护
  • Word Embeddings
  • 【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
  • VSCode 中 Git 添加了多个远端,如何设置默认远端
  • QT C++ new QTableWidgetItem 不需要删除指针
  • Leetcodehot100(链表篇)
  • N-bit ADC过采样和L阶噪声整形后的SQNR表达式
  • 火语言RPA--Excel关闭保存文档
  • 【落羽的落羽 数据结构篇】栈和队列
  • 从零开始学习服务网格:2025全面指南
  • 【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析⑰】
  • 基于 Redisson 分布式锁 实现报名人数限制功能
  • Python----数据结构(栈:列表栈,链栈。初始化,入栈,出栈,获取栈长度,判断是否为空,访问栈顶元素)
  • GcExcel