Linux Day26——传输层与三次握手


type: learning-note

title: Linux:传输层与三次握手(TCP vs UDP、端口与套接字、SYN → SYN-ACK → ACK)

date: 2026-10-23

description:传输层管到程序而非机器、端口 16 位与监听套接字、五元组唯一标识连接、TCP 有序可靠字节流、不保留消息边界、可靠≠绝对送达、UDP 数据报与校验和、UDP 不必然更快、三次握手三步(SYN/SYN-ACK/ACK)、握手证明什么没证明什么


2026-10-23 学习笔记

> 📌 GitHub:https://github.com/AR-firefly

笔记区

核心观点

**传输层:把包交给程序,不是交给机器**

  • 网际层(IP)只认"哪台机器",把包送到机器门口;传输层认"哪个程序",把包交到机器上对应的程序。

「传输层是为了让信息进入机器后能再把信息传给程序,否则程序得不到信息,网际层是给机器与机器直接交流的东西」

  • **端点**:一段对话的一头。两台程序说话,各占一头,合起来是两个端点。

  • 原文(LJ `transport-layer`):

> **英文原句**:The transport layer connects application endpoints across an IP network.

> **中文翻译**:传输层通过 IP 网络连接应用程序端点。

> **说人话**:IP 只把包送到机器门口;传输层负责把这包交到机器上具体哪个程序手里。

**端口:程序在机器上的号码**

  • 端口是 **16 位** → 2¹⁶ = **65536** 个编号,范围 **0--65535**。

  • 16 位 = 16 个二进制格子,每格 0 或 1 → 2¹⁶ = 65536 种组合。

  • 这套算法与 2026-10-22 算 `/20` 主机位的 2¹² 相同。

  • **监听**:程序想收数据,先在一个端口号上等着,这叫监听。

  • 包到了机器,系统看包里的**目标端口号**,交给正在那个号码上监听的程序。

「机器上有多个号码,号码数量为2的16次方,程序在这等着,等的位置叫端口,等的行为叫监听,包到了后,上面写着对应的号码,系统根据号码把包送给程序」

  • 原文:

> **英文原句**:A destination port helps the operating system deliver traffic to a listening socket.

> **中文翻译**:目标端口帮助操作系统把流量送达监听套接字。

> **说人话**:包身上写着"送到几号房间",系统就把它交到那个房间里等着的程序手上。

**五元组:唯一认出一条连接**

  • 只看一个端口分不出谁是谁;要认出"这是哪条连接"需要五项:

| 项 | 例子 |

| -------- | ------------ |

| 协议 | TCP |

| 源 IP | 192.168.1.10 |

| 源端口 | 50001 |

| 目的 IP | 1.2.3.4 |

| 目的端口 | 443 |

  • 两个客户端同时连同一台服务器:目的 IP + 目的端口一样,靠**源 IP + 源端口**不同区分。

  • **套接字**:一个端点 = IP + 端口;五元组 = 两个套接字 + 协议。

五元组**不是层层细分**(省 / 市 / 县那种),是**五个并列字段**组合起来。

  • 原文:

> **英文原句**:A connection or flow is identified by more than one port: protocol, source and destination addresses, and source and destination ports all matter. The same server port can therefore support many simultaneous clients.

> **中文翻译**:一条连接或流量不能只靠一个端口来标识:协议、源地址与目标地址、源端口与目标端口都很重要。因此同一个服务器端口可以同时支持许多客户端。

> **说人话**:认出"这是哪条连接"要看五个信息,不是只看一个端口号。

**TCP:有序、可靠、字节流**

  • 三个保证:

| 保证 | 什么意思 |

| ---------- | ---------------------------------------------- |

| **有序** | 发出去是第 1、2、3 段,收到的也按 1、2、3 排好 |

| **可靠** | 丢了的会重发,收到会回执 |

| **字节流** | 眼里只有"一串字节",没有"一条条消息" |

  • 手段:**序列号**(给字节编号)、**确认 ACK**(收到了就回)、**超时重传**(没回执就再发)。

  • `流量控制` / `拥塞控制` 只记名字,用到再查 `man 7 tcp`。

  • 原文:

> **英文原句**:TCP provides an ordered, reliable byte stream while a connection remains viable. It uses sequence numbers, acknowledgements, retransmission, flow control, and congestion control.

> **中文翻译**:只要连接仍然可用,TCP 就提供有序、可靠的字节流。它使用序列号、确认、重传、流量控制、拥塞控制。

> **说人话**:TCP 给你一条"按顺序、不丢、连着不断"的数据管道,靠编号和回执来做到。

**TCP 不保留消息边界**

  • 一次写入可能通过多次读取到达;多次写入也可能由一次读取返回。

  • 应用层必须自己规定"一条消息到哪结束"(成帧 / framing)。

  • 注意:TCP **不会改内容、不会乱顺序**;丢的是"分界"。反例:`hello world` 不会被拆成 `hell owo rld`(那等于改内容);真实情况是两条消息"你好"+"在吗"被一次读成"你好在吗"。

  • 原文:

> **英文原句**:TCP does not preserve application message boundaries: one write can arrive through several reads, or several writes can be returned by one read. Applications define their own framing.

> **中文翻译**:TCP 不保留应用程序消息边界:一次写入可能通过多次读取到达,多次写入也可能由一次读取返回。应用程序必须自行定义成帧方式。

> **说人话**:TCP 只管把这串字节按顺序送到,不管你一封信用了几次发、对方分几次收。

**"可靠"不等于"绝对送达"**

  • 连接会**超时**、被**重置**(RST)、或失败;重传不是无限的。

  • **ACK 只证明对方传输层收到**,不证明对方应用处理了。

「收到不代表成功,收到了只是说明人家刚刚开始处理,甚至收到就挂机不干了,永远处理不了」

  • 原文:

> **英文原句**:Reliability is not absolute delivery. A connection can time out, reset, or fail, and an acknowledgement does not prove that an application durably committed the data.

> **中文翻译**:可靠并不等于绝对送达。连接可能超时、重置或失败,而且确认并不能证明应用程序已持久提交了数据。

> **说人话**:TCP 的"可靠"只管到传输层为止,管不到"对方程序是不是真把东西存下来了"。

**UDP:数据报**

  • **有**:保留**数据报边界**(一次发一份,收也是一份)、**校验和**(能发现数据坏了)。

  • **没有**:连接状态、排序、重传、流量控制、拥塞控制。

  • 要可靠性、要重传,**应用自己加**。

  • 原文:

> **英文原句**:UDP preserves datagram boundaries and provides checksum-based error detection, but it does not provide TCP-style connection state, ordering, retransmission, flow control, or congestion control. An application can add any needed reliability or congestion behavior itself.

> **中文翻译**:UDP 保留数据报边界,并提供基于校验和的错误检测,但不提供 TCP 式的连接状态、排序、重传、流量控制或拥塞控制。应用程序可以自行添加所需的可靠性或拥塞行为。

> **说人话**:UDP 一次发一份,一份就是一份;但它不排队、不重发、不管对面忙不忙。

**UDP 并不必然更快**

  • 性能取决于四项:**协议设计、工作负载、路径、实现**。

  • 同一份 UDP 代码、同样数据量,A 机房比 B 机房慢很多 → 四项里**路径**不同(代码相同排除实现与设计,数据量相同排除负载)。

  • 原文:

> **英文原句**:UDP is not automatically faster; performance depends on protocol design, workload, path, and implementation.

> **中文翻译**:UDP 并不自动更快;性能取决于协议设计、工作负载、路径和实现。

> **说人话**:少了几道手续,不等于结果更快。

**三次握手:连接怎么建立**

  • 三步:

| 步 | 谁发给谁 | 带什么 |

| ----------- | --------------- | ------------------------------------ |

| ① `SYN` | 发起方 → 监听方 | 我的**初始序列号** |

| ② `SYN-ACK` | 监听方 → 发起方 | 我的**序列号** + **确认(ACK)你的** |

| ③ `ACK` | 发起方 → 监听方 | 确认你的 |

  • 结果:**两端各自建立传输状态**。

  • 「SYN,SYN+ACK和ACK,因为一次文件可以发送多个信息,第二次直接发SYN+ACK,省一次」

  • 纠正:"一次**报文**"可以同时携带 SYN 和 ACK 两个标志,不是"一次文件"。

  • 原文:

> **英文原句**:A normal TCP connection begins with a three-way handshake: 1. The initiator sends `SYN` with its initial sequence information. 2. The listener replies `SYN-ACK` with its own sequence information and acknowledgement. 3. The initiator returns `ACK`.

> **中文翻译**:正常的 TCP 连接以三次握手开始:1. 发起方发送带有初始序列信息的 `SYN`。2. 监听方回复 `SYN-ACK`,带上自己的序列信息和确认。3. 发起方返回 `ACK`。

> **说人话**:我报个起始编号给你,你收下、也报你的编号给我,我再说一声收到了 ------ 两边编号就对齐了。

**握手证明什么、没证明什么**

| 证明了 | 没证明 |

| ------------------------ | ------------------------------------ |

| 两头都能收发(双向可达) | 对面的**身份**(可能是假冒的服务器) |

| 编号起点对齐 | 对面**应用**能处理你的请求 |

| 两端各自建立传输状态 | 请求会成功 |

  • 「连接只保证你能连接上不保证你成不成功」

  • 原文:

> **英文原句**:This establishes transport state in both endpoints. It does not authenticate the application server or prove that the requested application operation will succeed.

> **中文翻译**:该过程在两个端点中建立传输状态。它不会验证应用服务器的身份,也不能证明所请求的应用操作会成功。

> **说人话**:握手只证明两头能互相收发、编号对上了;它不证明对面是谁,也不证明对面能替你办事。

关键方法/流程

**三次握手三步(带序列号)**

  1. 发起方 → 监听方:`SYN`,初始序列号 x

  2. 监听方 → 发起方:`SYN-ACK`,自己的序列号 y,确认号 x+1

  3. 发起方 → 监听方:`ACK`,确认号 y+1

  • **为什么三次不是四次**:第二步的 `SYN` 和 `ACK` 合并进同一个报文,省掉一次。

  • **为什么不是两次**:两次只能确认一方的编号,另一方的编号没被确认。

**一个端口怎么服务多个客户端**

  1. 目的 IP + 目的端口对所有客户端相同

  2. 源 IP + 源端口各不相同

  3. 五元组合起来唯一 → 一个监听端口可承载多条并发连接

实战记录

**① `grep -C 3` 对比:不带上下文 vs 带上下文**

不带上下文:

```

grep -n 'restart counter' /var/log/syslog | head -10

```

跑出来的输出(节选):

```

46:2026-10-18T10:13:21.062058+08:00 AR-firefly systemd1: wsl-pro.service: Scheduled restart job, restart counter is at 59.

61:2026-10-18T10:44:27.577990+08:00 AR-firefly systemd1: wsl-pro.service: Scheduled restart job, restart counter is at 60.

...

487:2026-10-18T21:49:29.725744+08:00 AR-firefly systemd1: wsl-pro.service: Scheduled restart job, restart counter is at 68.

```

带上下文:

```

grep -n -C 3 'restart counter' /var/log/syslog | head -30

```

多出来的关键行:

```

58-2026-10-18T10:24:27.029726+08:00 AR-firefly wsl-pro-service7090: WARNING Exiting after <nil>: check if the Windows agent is installed and running.

59-2026-10-18T10:24:27.032789+08:00 AR-firefly systemd1: wsl-pro.service: Deactivated successfully.

60-2026-10-18T10:24:27.033642+08:00 AR-firefly systemd1: wsl-pro.service: Consumed 1.611s CPU time over 31min 6.044s wall clock time, 61M memory peak.

```

  • 不带 `-C 3`:只看到"它每 31 分钟被重启一次",看不出原因。

  • 带上 `-C 3`:看到 `WARNING Exiting ... check if the Windows agent is installed and running` ------ 它因为 Windows agent 不可用而退出,systemd 再拉起来。

  • **`-C 3` 给的是候选上下文,不是答案**:同一段里也混着 `chronyd`、`systemd-resolved` 的无关行,要自己挑。

**② 三次握手报文排序**

给三个打乱的报文:

  • 报文 A:`ACK`,确认号 x+1

  • 报文 B:`SYN`,序列号 x

  • 报文 C:`SYN-ACK`,序列号 y,确认号 x+1

排出的顺序:**B(初始序列号)→ C(序列号 + 确认对方)→ A(确认对方)**


线索区(学完后合上材料,自问自答)

**Q: 传输层和网际层的分工是什么?**

A: IP 管到机器;传输层管到程序。包到了机器还没到程序,传输层负责交到对应的程序。

**Q: 端口是几位、一共多少个、范围是多少?**

A: 16 位;2¹⁶ = 65536 个;0--65535。

**Q: 包到了机器上,系统看哪一项决定交给哪个程序?**

A: 包里的**目标端口号**,按号码交给正在那个号码上监听的程序。

**Q: 五元组是哪五项?为什么需要五个?**

A: 协议 + 源 IP + 源端口 + 目的 IP + 目的端口。只看端口分不出哪条连接是哪条;目的那侧相同时,靠源 IP + 源端口区分。

**Q: TCP 保证哪三件事?靠什么手段做到?**

A: 有序(序列号)、可靠(ACK + 超时重传)、字节流;另有流量控制、拥塞控制。

**Q: 用 TCP 一次写 100 字节,对方分两次读到 60 + 40,可能吗?为什么?**

A: 可能。写的次数和读的次数没有对应关系;TCP 不保留消息边界。

**Q: TCP 会改内容和顺序吗?**

A: 不会。它保证内容和顺序,丢的是"分界",不是"内容"。

**Q: 收到 ACK 就等于对方应用处理完了吗?为什么?**

A: 不等于。ACK 只证明对方传输层收到了;应用可能还没处理、处理失败,或收到就崩了。

**Q: UDP 保留了哪样、缺了哪几样?**

A: 保留数据报边界、有校验和;缺连接状态、排序、重传、流量控制、拥塞控制。

**Q: UDP 丢了包谁补?**

A: 应用自己。UDP 不重传、不通知。

**Q: UDP 一定比 TCP 快吗?**

A: 不一定。看协议设计、工作负载、路径、实现四项。

**Q: 三次握手三步各带什么信息?**

A: `SYN` 带初始序列号;`SYN-ACK` 带自己的序列号和对方的确认;`ACK` 确认对方。

**Q: 为什么是三次不是四次?**

A: 第二步的 `SYN` 和 `ACK` 可以合在同一个报文里。

**Q: 握手证明了什么、没证明什么?**

A: 证明双向可达、编号对齐、两端建立传输状态;不证明对方身份、应用能处理、请求会成功。

**Q: "通了"和"能用"差在哪?**

A: 通 = 传输层两端能收发;能用 = 应用层真的处理请求并成功返回。握手的证据只到前者。


总结(50字以内,用自己的话概括今天学到了什么)

IP 送到机器,端口送到程序;TCP 用编号和回执保有序可靠,UDP 留边界不补丢;三次握手对齐编号,只证明通不证明能用。


复习卡片

| 概念 | 必学/了解 | 一句话 | 场景 |

| ------------------- | --------- | ------------------------------------------- | ------------------------ |

| 传输层 | 必学 | 把流量交给应用程序端点,不是交给机器 | 分清机器不通还是程序不通 |

| 应用程序端点 | 必学 | 一段对话的一头;两台程序各占一头 | 描述连接两端 |

| 端口 | 必学 | 程序在机器上的号码,16 位 → 0--65535 | 找哪个程序在收 |

| 监听 | 必学 | 程序在某个端口号上等着收数据 | 判断服务在不在 |

| 目标端口 | 必学 | 系统据此把包交给对应程序 | 读包、读 ss |

| 套接字 | 必学 | 一个端点 = IP + 端口 | 描述连接 |

| 五元组 | 必学 | 协议 + 两 IP + 两端口 = 5 项 | 唯一认出连接 |

| TCP | 必学 | 传输层协议:有序、可靠、字节流 | 判断能不能忍丢 |

| 字节流 | 必学 | 一串字节,没有消息分界 | 解释为什么要成帧 |

| 序列号 | 必学 | 给字节编号,用于排序和发现缺失 | 解释有序与重传 |

| ACK | 必学 | 收到的回执;只到传输层 | 判断"收到≠处理" |

| 消息边界 | 必学 | 一条消息到哪结束;TCP 不保留 | 应用协议必须自己定 |

| 可靠 ≠ 绝对送达 | 必学 | 会超时、重置、失败;ACK 不证明应用提交 | 排障不误判 |

| 重置 / RST | 必学 | 连接被强制掐断,对比 FIN 正常关闭 | 看连接异常断 |

| UDP | 必学 | 传输层协议:保留数据报边界、有校验和 | 判断要不要 TCP |

| 数据报 | 必学 | 一份独立数据,自带边界 | 解释 UDP 的边界 |

| 校验和 | 了解 | 发现数据坏了的校验值;`man 7 udp` | 锚点,用到再讲 |

| 工作负载 | 了解 | 系统要处理多少活、多频繁 | 判断性能 |

| SYN | 必学 | Synchronize 前三个字母;"我要和你对表" | 看握手第一个报文 |

| SYN-ACK | 必学 | 一个报文同时做同步和确认 | 看握手第二个报文 |

| 三次握手 | 必学 | SYN → SYN-ACK → ACK,两端建立传输状态 | 讲清连接建立 |

| 握手不证明什么 | 必学 | 不验证身份、不证明应用操作成功 | 判断服务可用 |

| 流量控制 / 拥塞控制 | 了解 | TCP 的两套调速机制;`man 7 tcp` | 锚点,用到再讲 |

| `ss` | 了解 | 看监听与已连接套接字;第 4 天讲;`man 8 ss` | 预览 |

| `/etc/services` | 了解 | 端口名对照表;`man 5 services` | 预览 |


流程附加段

旧知识回收

| 概念 | 一句话 | 出处 |

| ------------ | ------------------------------------------ | ----------------------------------------------- |

| 端口分拣 | 系统看目标端口,交给监听它的程序 | 收尾检索第 2 问先说"不知道",补讲后重考答"端口" |

| TCP 三保证 | 有序 / 可靠 / 字节流;序列号 + ACK + 重传 | 收尾检索第 4 问不知道,补讲后重考答全 |

| 五元组内容 | 协议 + 源 IP + 源端口 + 目的 IP + 目的端口 | 收尾检索第 3 问说"分别是啥记不得了",当场补 |

| 四因素 | 设计 / 负载 / 路径 / 实现 | 收尾检索第 8 问漏"工作负载",当场补 |

| TCP 不改内容 | 只丢分界,不会把 hello world 拆乱 | 收尾检索第 5 问例子举错,当场纠 |

今日产出验收

| 产出项(来源 `S1块4开周清单.md:67`) | 用户的回答 | 判定 |

| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---- |

| 讲清三次握手三步(含序列信息) | 「SYN,SYN+ACK和ACK」「B带初始序列号,C序列号 + 确认对方的ACK,A确认对方的ACK」 | ✅ |

| 说清它证明了什么、没证明什么 | 「证明两头都能收发,编号起点对齐,两端建立传输状态,但不知道对方是身份,不一定成功,对面也不一定能处理你的请求」 | ✅ |

| 说清 TCP 与 UDP 差在哪(可靠 / 有序 / 边界) | 「有序,可靠,字节流......UDP 保留信息边界和校验和,少了连接状态,排序,重传和流量控制 / 拥塞控制」 | ✅ |

相关推荐
隔窗听雨眠2 小时前
PostgreSQL单表从Windows迁移到Linux:差异剖析、方案对比与全流程实战
linux·windows·postgresql
xinruoqianqiu2 小时前
记录Linux
linux
额额额对了2 小时前
嵌入式 Linux 实战:i.MX6ULL 上的 CAN 通信与摄像头采集
linux·运维·服务器
牛马鸡niumasi2 小时前
【Linux】进程替换
linux
RFID科技的魅力3 小时前
2026 年 RFID 资产标签批量制作怎么做?RFID 标签打印机实操指南
运维·人工智能·嵌入式硬件·物联网
灯澜忆梦3 小时前
【Linux】#10 | Linux 终端实用快捷键 + 安装应用
linux·运维·服务器
码士集团小青4 小时前
面霸篇:高频 Java 基础问题(核心卷一)
linux·服务器·数据库·redis·缓存·1024程序员节
水饺编程4 小时前
第2章:Linux 基础,切换用户
linux·c语言·汇编
Lsetea5 小时前
curl指定--tlsv1.2仍连接TLS1.3:最低版本与tls-max排查
linux·https·ssl证书·curl·tls