技术知识文章集合TECHNICAL ARCHIVE · 457 DOCUMENTS

显示模式

登录
ARCHIVE DOCUMENTNET

通俗大白话来理解 TCP 协议的三次握手和四次分手

所属馆藏
NET Protocol
文件格式
Markdown
原始路径
NET Protocol/36-通俗大白话来理解TCP协议的三次握手和四次分手
本文目录12 个章节
  1. 一、先用“大白话”理解三次握手
  2. 二、为什么不是两次握手?
  3. 三、HTTP 连接、Socket 和 TCP 连接
  4. 四、TCP 是什么?
  5. 五、TCP 首部
  6. 六、TCP 三次握手的过程
  7. 七、为什么要三次握手?
  8. 八、TCP 四次挥手
  9. 九、为什么要四次挥手?
  10. 十、浏览网页时的 TCP 示例
  11. 十一、常见误区总结
  12. 参考资料

通俗大白话来理解 TCP 协议的三次握手和四次分手

Category(分类): NET Protocol Status: 未知

原文参考:TCP 三次握手和四次挥手

本文保留原文“生活对话”和状态变化的讲解方式,同时修正 HTTP、Socket、TCP 首部、PSH、三次握手、四次挥手和 TIME-WAIT 等容易误解的内容。

一、先用“大白话”理解三次握手

第一次对话:你能听到我吗?

老婆让甲出去打酱油。甲在路上碰到朋友乙,于是问了一句:“哥们,你吃饭了吗?”

乙戴着耳机没有听到,也没有反应。甲无法确认乙能不能收到自己的话,因此沟通没有建立。

这可以类比为客户端发送:

SYN,seq = x

客户端发送 SYN 后进入 SYN-SENT,等待服务端回应。

第二次对话:我听到了,也能回答你

如果乙听到了甲的话,但只是随便回答一句无法理解的内容,甲仍然不能确认乙是否真的理解并参与这次对话。

如果乙正确回应,并且反问“我吃了,你呢?”,甲就知道:乙收到了自己的请求,也能从乙那里收到回应。

这可以类比为服务端发送:

SYN + ACK,seq = y,ack = x + 1

服务端确认客户端的 SYN,同时发送自己的 SYN。服务端随后进入 SYN-RECEIVED 状态。

第三次对话:我也听到了你的回答

甲收到乙的回答后,再回复:“我也吃了。”乙收到这句回复后,才知道甲确实收到了自己的回答。

这可以类比为客户端发送:

ACK,ack = y + 1

第三次握手的 ACK 让服务端知道客户端已经收到了第二次握手的内容。双方随后进入 ESTABLISHED 状态,可以正常传输 TCP 字节流。

TCP 三次握手示意图

这个生活例子只是帮助理解,不能把它当成 TCP 状态机的完整定义。三次握手的核心目的包括:

  • 协商和确认双方的 Initial Sequence Number(ISN);
  • 确认双方都具备发送和接收 TCP 报文的能力;
  • 让服务端不会仅凭一个旧的、延迟到达的 SYN 就错误建立连接;
  • 为后续的可靠、有序字节流传输建立必要状态。

第三次 ACK 并不等于应用程序已经准备好,也不代表业务请求已经成功。

二、为什么不是两次握手?

原文用“被风吹走的旧招呼”来解释这个问题:

甲第一次打招呼的消息在网络中延迟了很久。后来甲重新发起连接,双方完成两次或三次交互并很快关闭连接。此时,旧的连接请求才到达乙。

如果只采用两次握手,乙收到旧请求后可能认为新的连接已经建立,并为这个实际上不存在的连接保留资源。真正的甲并没有发送后续确认,也不会使用这个连接,乙却可能一直等待,造成资源浪费。

第三次握手让服务端获得客户端对第二次握手的明确确认。在经典 TCP 状态机中,服务端不能仅凭收到客户端 SYN、发出 SYN+ACK 就把连接视为双方已经完成确认。

因此,“三次握手是为了确认双方都能互相听见”是便于入门的说法;更严谨地说,它是为了在可能丢包、延迟、重复的网络中同步序列号,并让双方对连接建立状态达成一致。

需要注意,三次握手不是对所有可靠通信问题的万能理论结论,也不是说网络中只要有三次消息就绝对可靠。它是 TCP 连接建立过程针对特定状态和序列号需求所采用的最小交互流程。

三、HTTP 连接、Socket 和 TCP 连接

1. HTTP 连接

HTTP 是应用层的请求—响应协议,通常运行在 TCP + TLS 之上;HTTP/3 则运行在 QUIC 之上。HTTP 的一次请求通常对应服务器的一次响应,但现代 HTTP 还支持持久连接、流式响应、升级到 WebSocket、HTTP/2 多路复用等机制,不能一概说“每次请求结束后都会主动释放连接”。

  • HTTP/1.0 默认通常使用短连接,但 Keep-Alive 扩展可以复用连接;
  • HTTP/1.1 默认支持持久连接;
  • HTTP/1.1 管线化允许连续发送请求,但响应顺序会带来队头阻塞,因此实际浏览器较少使用;
  • HTTP/2 在一条 TCP 连接中复用多个 Stream;
  • HTTP/3 使用 QUIC Stream,底层不再是 TCP。

服务器主动向客户端发送数据也不一定只能靠轮询。根据需求可以使用:

  • 长轮询;
  • Server-Sent Events(SSE);
  • WebSocket;
  • HTTP 流式响应;
  • HTTP/2 或其他应用层机制。

“定时发送请求就表示客户端在线”也只是应用层约定。TCP 连接保持或 TCP Keepalive 只能说明一定程度的网络可达性,不能证明用户在线或业务服务正常。

2. Socket 是什么

Socket(套接字)是操作系统提供的网络通信接口和端点抽象。一个 TCP 连接通常可以由以下信息共同识别:

传输协议 + 源 IP + 源端口 + 目的 IP + 目的端口

应用通过 Socket API 使用 TCP、UDP 等传输协议。不同系统的 Socket 细节不同,但核心作用都是让多个应用进程和网络连接能够并发使用网络资源。

3. 建立 Socket 连接

以 TCP 服务端为例,典型过程是:

  1. 服务端创建监听 Socket,绑定 IP 和端口并调用 listen()
  2. 客户端调用 connect() 发起 TCP 三次握手;
  3. 服务端完成握手后,accept() 返回一个新的已连接 Socket;
  4. 原来的监听 Socket 继续接受其他连接。

accept() 返回新 Socket 不等于服务端一定要创建新线程。服务端可以使用线程、进程、事件循环、线程池或 IO 多路复用处理连接,这是实现选择,不是 TCP 协议要求。

UDP Socket 通常不需要 TCP 意义上的连接握手。某些系统允许对 UDP Socket 调用 connect(),但这主要用于固定默认对端、过滤来源或接收错误通知,不代表 UDP 获得了 TCP 的可靠传输能力。

4. Socket 连接与 HTTP 连接

Socket 是更底层的通信接口,TCP Socket 建立后,双方可以按应用协议传输字节;HTTP 则规定了请求、响应、首部、状态码和消息内容等应用层语义。

网络中的防火墙、NAT 和负载均衡器可能清理长时间空闲的状态,因此应用有时会设计心跳。但心跳的具体格式、超时和重连策略属于应用层,不是 TCP 自动判断“用户在线”的机制。

四、TCP 是什么?

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接、可靠、有序、基于字节流的传输层协议。

TCP 不保留应用层消息边界。应用连续调用两次 send(),接收端可能一次读到两次发送的全部内容,也可能只读到其中一部分。因此应用协议仍然需要自行设计长度前缀、分隔符或其他消息封装方式。

1. TCP/IP 与 OSI 模型

OSI 七层模型示意图

TCP 工作在传输层,IP 工作在网际层,ARP 与以太网等协议通常与链路层相关。OSI 七层模型和 TCP/IP 模型不是严格的一一对应关系,实际协议可能跨越或组合多个层次。

在常见的术语中:

  • 链路层传输的数据常称为 Frame;
  • IP 层传输的数据常称为 Packet;
  • TCP 层传输的数据常称为 Segment;
  • UDP 层传输的数据常称为 Datagram。

数据从应用层向下发送时,通常会经过封装;接收端向上交付时会经过解封装。不同网卡卸载和内核实现可能让抓包工具显示出不同的分段结果,但不改变应用层协议语义。

数据封装和解封装示意图

五、TCP 首部

TCP 首部结构

TCP 首部包含源端口、目的端口、序列号、确认号、数据偏移、标志位、窗口、校验和、紧急指针和可选字段等信息。

  • Source Port / Destination Port:各占 16 位,与源 IP、目的 IP 和传输协议共同标识连接;
  • Sequence Number:标识发送方向的字节序号。SYN 和 FIN 各消耗一个序列号,普通数据按照字节数递增;
  • Acknowledgment Number:表示发送端期望收到的下一个序号,通常是累计确认。它帮助可靠传输,但 ACK 本身不会阻止丢包;
  • Data Offset:表示 TCP 首部长度,占 4 位。首部长度最小为 20 字节,带选项时最大为 60 字节;
  • Window:接收窗口字段,用于流量控制。窗口扩大选项可以让实际接收窗口超过 16 位字段直接表示的范围;
  • Checksum:检测 TCP 首部、数据和伪首部中的传输错误;
  • Urgent Pointer:在 URG 有效时指示紧急数据相关位置,现代应用很少依赖 TCP urgent data;
  • Options:可携带 MSS、窗口扩大、SACK、时间戳等选项。

TCP 标志位示意图

TCP 标志位

早期资料通常列出 6 个基本标志位:URGACKPSHRSTSYNFIN。现代 TCP 还涉及 ECN 相关的 ECECWR,规范格式中还可见 NS,因此不能再说 TCP 永远只有 6 个控制位。

  • URG:表示紧急指针字段有效,不能理解为“保证连接不中断”或“要求中间设备优先处理”;
  • ACK:表示确认号字段有效。连接建立后,正常 TCP 报文通常都带 ACK,但 SYN 初始报文等特殊报文除外;
  • PSH:提示接收端尽快向应用交付已有数据,但它不是应用消息边界,也不是可靠的“立即发送”按钮;
  • RST:复位连接,通常用于拒绝连接、报告异常或终止无效状态;
  • SYN:同步序列号,用于连接建立和初始序列号协商;不是“synchronous 建立联机”;
  • FIN:表示发送方不会再发送该方向的数据,但另一方向仍可能继续传输;FIN 是半关闭,不代表双方同时结束。

SYN 扫描时收到 SYN+ACK 通常表示目标端口可能处于监听状态,收到 RST 通常表示端口关闭或连接被拒绝。扫描结果会受到防火墙、NAT、SYN cookies 和过滤策略影响,不能简单据此判断主机“安全”或“存在”。

六、TCP 三次握手的过程

TCP 三次握手过程

第一次握手:客户端发送 SYN

客户端发送连接请求报文:

SYN = 1
Sequence Number = x

客户端进入 SYN-SENT 状态,等待服务端确认。

第二次握手:服务端发送 SYN + ACK

服务端收到客户端的 SYN 后,发送:

SYN = 1
ACK = 1
Sequence Number = y
Acknowledgment Number = x + 1

这一步同时确认客户端的 SYN,并把服务端自己的初始序列号告诉客户端。服务端进入 SYN-RECEIVED 状态。

第三次握手:客户端发送 ACK

客户端收到服务端的 SYN+ACK 后,发送:

ACK = 1
Acknowledgment Number = y + 1

服务端收到最终 ACK 后进入 ESTABLISHED;客户端通常在收到 SYN+ACK 并发送 ACK 后进入 ESTABLISHED

正常 TCP 连接的 SYN 报文通常不携带应用数据,但 TCP Fast Open 等机制允许在握手阶段携带数据。即使没有使用 Fast Open,客户端也可能把应用数据放在第三次握手的 ACK 之后或与 ACK 合并发送,不能绝对地说“握手完成前永远没有数据”。

一个抓包示例

192.168.1.116:3337 > 192.168.1.123:7788: SYN seq=3626544836
192.168.1.123:7788 > 192.168.1.116:3337: SYN,ACK seq=1739326486 ack=3626544837
192.168.1.116:3337 > 192.168.1.123:7788: ACK ack=1739326487

解释如下:

  1. 客户端发送 SYN,初始序列号为 3626544836
  2. 服务端确认客户端的 SYN,因此 ACK 为 3626544837,同时发送自己的 SYN,序列号为 1739326486
  3. 客户端确认服务端的 SYN,因此 ACK 为 1739326487

SYN 消耗一个序列号,所以确认号会在对方初始序列号的基础上加 1。

七、为什么要三次握手?

谢希仁《计算机网络》中常用“防止已失效的连接请求报文段突然到达服务端”的例子来解释三次握手:

  1. 客户端曾经发送了一个连接请求,但这个报文在网络中延迟了;
  2. 客户端后来重新建立连接并关闭;
  3. 旧的连接请求此时才到达服务端;
  4. 如果服务端只通过一次响应就认为连接建立,可能为一个并不存在的连接分配资源;
  5. 三次握手要求客户端再发送最终 ACK,服务端收不到这个 ACK 时,就能知道客户端并没有真正确认这次连接。

延迟重复报文导致旧连接请求的示意图

更严谨地说,三次握手用于在不可靠网络中同步序列号,并让双方确认对方能够收发相关 TCP 报文。它不负责验证用户身份、加密通信,也不保证应用层业务成功。

八、TCP 四次挥手

TCP 是全双工协议,两个方向的数据流可以分别关闭。因此,主动关闭方发送 FIN 后,只表示自己不再发送数据,但仍然可以接收对方数据。

典型关闭过程

  1. 第一次挥手:主动关闭方发送 FIN,进入 FIN-WAIT-1,表示本方向没有更多数据要发送;
  2. 第二次挥手:被动方收到 FIN 后返回 ACK。这个 ACK 只表示已经收到 FIN,不代表“同意立即关闭”。被动方进入 CLOSE-WAIT,仍可以发送剩余数据;主动方收到 ACK 后进入 FIN-WAIT-2
  3. 第三次挥手:被动方的应用也关闭发送方向,发送 FIN,并进入 LAST-ACK
  4. 第四次挥手:主动方收到 FIN 后发送 ACK,进入 TIME-WAIT;被动方收到 ACK 后进入 CLOSED。主动方等待定时器到期后也进入 CLOSED

TCP 四次挥手过程

严格来说,实际报文不一定正好是四个:ACK 和 FIN 可能合并,同时关闭时状态和报文顺序也会不同。所谓“四次挥手”是典型主动关闭流程的教学简称。

关闭状态

  • FIN-WAIT-1:本端已发送 FIN,等待对端 ACK 或 FIN;
  • FIN-WAIT-2:本端 FIN 已被确认,等待对端发送 FIN,本端仍可接收数据;
  • CLOSE-WAIT:收到对端 FIN,已发送 ACK,等待本地应用关闭发送方向;
  • LAST-ACK:本端已发送 FIN,等待对端确认;
  • TIME-WAIT:本端已确认对端 FIN,等待一段时间以处理可能重传的 FIN/ACK 和旧报文;
  • CLOSED:连接不存在。

TIME-WAIT 常用 2MSL 作为教学上的等待时间。它不是“等待服务器回复来证明服务器正常关闭”,而是为了保证:

  • 如果最后一个 ACK 丢失,本端可以对重传的 FIN 再次发送 ACK;
  • 旧连接中的延迟报文不会干扰后续使用相同地址和端口的连接。

如果在 FIN-WAIT-1 收到对方 FIN,可能进入 CLOSING 等状态;同时关闭、FIN 与 ACK 合并等情况都会导致状态路径和报文数量不同。

九、为什么要四次挥手?

TCP 是全双工模式,客户端到服务端、服务端到客户端是两个相对独立的数据方向。

当主机 1 发送 FIN 时,只表示主机 1 已经没有数据发送给主机 2;主机 1 仍可以接收主机 2 的数据。主机 2 先返回 ACK,再等待自己的应用数据发送完毕,之后才发送 FIN。主机 2 的 FIN 被主机 1 确认后,两个方向才都完成关闭。

所以,典型情况下需要:

主机 1 -> 主机 2:FIN
主机 2 -> 主机 1:ACK
主机 2 -> 主机 1:FIN
主机 1 -> 主机 2:ACK

这不是一定要四个独立报文:如果某一方已经没有待发送数据,ACK 和 FIN 可以在同一报文中携带;如果双方同时关闭,也会进入不同状态。

十、浏览网页时的 TCP 示例

浏览器访问网页时,可能先进行 DNS 查询,然后建立 TCP 连接;如果是 HTTPS,还会进行 TLS 握手;之后发送 HTTP 请求并接收响应。现代浏览器还可能复用 HTTP/1.1 连接、使用 HTTP/2 多路复用,或者直接使用 HTTP/3 + QUIC,因此不能把所有网页访问都简化成“每次请求重新 TCP 三次握手”。

浏览器访问网页中的 TCP 示例

一次典型的 HTTP/1.1 over TCP 流程可以简化为:

TCP 三次握手
TLS 握手(HTTPS 场景)
HTTP 请求
HTTP 响应
连接复用或关闭

TCP 的作用不只是流量控制,而是提供可靠、有序的字节流,并结合连接管理、确认、重传、接收窗口和拥塞控制等机制完成传输。

十一、常见误区总结

  • TCP 三次握手不是身份认证,也不是加密机制;
  • SYN 是 TCP 标志位,ISN 才是 Initial Sequence Number;
  • TCP 是字节流,不保留应用层消息边界;
  • ACK 确认已收到的字节范围,但不代表业务处理成功;
  • PSH 不是消息边界,也不是可靠的立即发送命令;
  • FIN 只关闭一个方向,TCP 支持半关闭;
  • ACK 不代表“同意关闭”,只代表确认收到报文;
  • 四次挥手是典型流程,实际可能合并或同时关闭;
  • TIME-WAIT 不是等待服务器证明自己关闭,而是保护连接复用和最后 ACK;
  • Socket 服务端不一定为每个连接创建线程;
  • HTTP/1.1、HTTP/2 和 HTTP/3 的连接模型不同。

我想你应该懂了

TCP 是一个复杂的协议。本文主要介绍了 TCP 连接建立和关闭过程,以及 Socket、HTTP 和 TCP 首部之间的关系。真正学习 TCP 时,还需要继续理解滑动窗口、拥塞控制、SACK、重传计时器、SYN cookies、连接复用和 TCP Fast Open 等内容。

参考资料

457 DOCUMENTS · 10 COLLECTIONS
ARCHIVE SEARCH457 篇文章

SEARCH GUIDE

输入关键词开始搜索

支持搜索文章标题、所属分类和原始文档路径。

按分类浏览

10 COLLECTIONS