专栏: 《计算机网络基础》
对应总览: 第三章 · 第三篇 传输层:可靠与实时的取舍
本篇角色: 传输层「开篇导论」------先建立取舍观,再逐个深挖 UDP / TCP / QUIC
层目标: 理解 端到端 如何交付字节流或数据报
读完你能: 分清 TCP/UDP/QUIC;解释端口与五元组;用
ss看连接;知道「连不上端口」该查什么
导读:应用层点完餐,谁负责「送到」?
上一篇说:应用层管「说什么」(HTTP、DNS...)。
可是话说给谁听?丢了要不要重送?塞车了怎么刹车?
这些事,轮到 传输层(Transport Layer)。
你(浏览器) 对方(网站进程)
┌──────────┐ ┌──────────┐
│ HTTP内容 │ │ HTTP内容 │ ← 应用层:听得懂吗?
├──────────┤ ├──────────┤
│ TCP/UDP │ ◄──── 端到端送达 ────► │ TCP/UDP │ ← 传输层:送到哪个程序?
├──────────┤ ├──────────┤
│ IP │ │ IP │ ← 网络层:送到哪台机器?
└──────────┘ └──────────┘
人话版层目标:
网络层把包送到「那台电脑」;传输层把数据交到「那个程序」。
顺带决定:要不要像挂号件一样可靠,还是像平邮一样图快。
flowchart TB
APP[应用层:HTTP / DNS / gRPC...] --> T[传输层:端口 + 可靠/尽力]
T --> IP[网络层:IP 找主机]
IP --> L2[链路/物理:邻站搬运]
一、概念:传输层在解决哪两个灵魂问题?
1.1 问题一:一台机器好多程序,数据给谁?
服务器上可能同时跑:
网站 :443
数据库 :5432
SSH :22
监控 :9100
只靠 IP 不够------IP 只认到主机。
传输层用 端口号(0~65535) 当「窗口号 / 房间号」。
┌─────────────────────────────┐
│ 服务器 203.0.113.10 │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │:443 │ │:22 │ │:53 │ │
│ │Web │ │SSH │ │DNS │ │
│ └─────┘ └─────┘ └─────┘ │
└─────────────────────────────┘
1.2 问题二:要可靠,还是要实时?
网络会丢包、乱序、重复------这是常态。
| 选择 | 像什么 | 代表 |
|---|---|---|
| 可靠优先 | 挂号件:丢了重寄、按序签收 | TCP |
| 实时优先 | 平邮/直播:丢几帧就丢了 | UDP |
| 现代折中 | 在 UDP 车上做更聪明的可靠与多路复用 | QUIC(HTTP/3 常用) |
总览说的「可靠与实时的取舍」,指的就是这件事。
1.3 「端到端」是什么意思?
端到端 = 从你的进程 ──► 到对方进程
(中间路由器主要认 IP,不太懂你的端口语义)
路由器一般不拆 TCP 去「帮你重传」(少数中间盒另说)。
重传、确认、拥塞控制,主要发生在两端的传输层。
二、原理:先认三辆车------UDP、TCP、QUIC
2.1 协议地图(对照总览)
| 协议 | 一句话 | 原理抓手 | 典型应用 | 坏了什么样 |
|---|---|---|---|---|
| UDP | 无连接、尽力而为 | 端口、可选校验、不重传 | DNS、直播、游戏、QUIC 底座 | 防火墙丢 UDP;自己要处理丢包 |
| TCP | 面向连接、可靠字节流 | 握手/挥手、序号 ACK、重传、窗口、拥塞控制 | Web、文件、数据库、SSH | SYN 丢、重传飙高、RST、TIME_WAIT |
| QUIC | 更现代的传输(常跑在 UDP 上) | 多路复用、0-RTT、连接迁移 | HTTP/3 | UDP 被墙、回落、握手耗时 |
| 端口与多路复用 | 一机多服务如何共存 | 五元组 | 所有连接 | 端口占用、连接表爆 |
2.2 UDP:把明信片扔进邮筒
发送方:写上「寄给 端口53」→ 发出去
接收方:收到就收;丢了 UDP 不管
特点(先建立直觉):
-
无握手:来得快
-
无保证: 可能丢、乱序、重复
-
头开销小
-
适合: 问一句答一句(DNS)、能容忍丢帧的音视频

2.3 TCP:先握手,再当「可靠管道」
TCP 提供的是 字节流:你写入的字节,对端按序读出(中间被切成很多段传输,但对应用像水管)。
三次握手(为什么要三步?)
打电话类比:
你:喂,听得到吗? SYN
对方:听得到,你那边呢? SYN+ACK
你:好,开说。 ACK
客户端 服务器
│──────── SYN ────────────►│
│◄────── SYN+ACK ──────────│
│──────── ACK ────────────►│
│ 连接建立,可传数据 │
目的直觉:
-
双方确认「对方真的在、收发能力正常」;
-
同步初始序号,后面才能发现丢包/重复。
四次挥手(为啥常是四次?)
TCP 全双工:你说完了,对方可能还有话要说。
你:我说完了(FIN)
对方:知道了(ACK)......对方可能继续发完剩余数据
对方:我也说完了(FIN)
你:好(ACK)
细节与状态机留给 TCP 专章;本篇先建立「分手也要交代清楚」。
可靠靠什么?(三件套直觉)
① 序号 + ACK:对方确认收到哪一段
② 超时重传: 等不到 ACK 就再发
③ 滑动窗口: 一次可以「在途」多少数据(别把对方灌爆)
2.4 流量控制 vs 拥塞控制(务必分清)
很多人混为一谈,用快递站类比:
| 流量控制 | 拥塞控制 | |
|---|---|---|
| 怕谁忙不过来 | 接收方处理不过来 | 整条路径/网络堵了 |
| 像什么 | 对方仓库货架满了,先别狂发 | 高速路堵车,大家一起减速 |
| TCP 里 | 接收窗口(rwnd)等 | 拥塞窗口(cwnd)、慢启动等 |
发送方
│
│ 既不能超过接收方能力(流量控制)
│ 也不能把互联网挤爆(拥塞控制)
▼
网络路径 ──► 接收方
弱网时网页「一顿一顿」,常常和 丢包 + 拥塞控制降速 有关(后文结合延迟/带宽篇更有感)。
2.5 队头阻塞:TCP 与 HTTP 版本的恩怨
HTTP/1.1 经典痛点:
一条 TCP 上请求排队,前面一个慢,后面全等
(应用层队头阻塞)
HTTP/2:
一条 TCP 上多路复用多个请求
但 TCP 丢一个包,整条连接仍可能卡住
(传输层队头阻塞仍在)
HTTP/3 / QUIC:
流之间更独立,一个流丢包少连累其它流
HTTP/1.1: 请求1 ████░░░░ 请求2 要等1
HTTP/2: 流1 ██ 流2 ██ 流3 ██ (同 TCP,丢包仍可能大家一起停)
QUIC: 流1 ██ 流2 ██ (更少「一人感冒全家吃药」)
这就是总览点名要讲的:队头阻塞:TCP 与 HTTP/1.1、HTTP/2 的关系。
2.6 QUIC:为什么说它「基于 UDP」?
┌─────────────────────┐
│ HTTP/3 │
├─────────────────────┤
│ QUIC(连接、多路、加密等)│
├─────────────────────┤
│ UDP │
├─────────────────────┤
│ IP │
└─────────────────────┘
直觉:
-
复用 UDP 端口模型与穿越能力;
-
在用户态把「可靠、多路、握手优化」做强;
-
手机换基站时 连接迁移 更友好(细节专章展开)。
2.7 五元组:怎么认出「这一条连接」?
TCP/UDP 通信常用 五元组 标识一条会话:
协议 + 源IP + 源端口 + 目的IP + 目的端口
例子:
tcp 192.168.1.8:53122 → 93.184.216.34:443
你的浏览器临时端口 53122
│
▼
五元组唯一标出「这一次」访问
│
▼
服务器 443 上的网站进程
NAT、防火墙、连接跟踪,很多都围着五元组转。
三、应用:日常生活与开发里怎么选车?
3.1 选型速查
| 场景 | 更常选 | 原因 |
|---|---|---|
| 网页、接口、文件、数据库 | TCP(或 HTTP/3→QUIC) | 要完整、有序 |
| DNS 查询 | UDP(大响应可转 TCP) | 短平快 |
| 直播、实时游戏 | UDP + 应用自己补救 | 要低延迟 |
| 现代浏览器 HTTPS | TCP+TLS 或 HTTP/3/QUIC | 视浏览器与服务器支持 |
3.2 开发者最小心智模型
写业务代码
└─ 用 HTTP 客户端 / 数据库驱动
└─ 底层多半已是 TCP
└─ 你要关心的:超时、重试、连接池、TIME_WAIT、端口耗尽
做实时音视频
└─ 常直接/间接碰 UDP
└─ 你要关心的:丢包、抖动缓冲、拥塞、防火墙 UDP
3.3 和「打开网页」时间线的衔接
DNS(应用,常 UDP/53)
→ TCP 三次握手(传输)
→ TLS(安全)
→ HTTP(应用)
卡在「Connect」很久:优先怀疑 TCP/路径/防火墙 。
卡在 SSL:TLS。
卡在 Waiting:服务器应用。
四、问题定位:传输层怎么查?(实操)
4.1 分层对照
ping IP 通,端口不通 → 传输层/防火墙/未监听
大量重传、吞吐上不去 → 丢包、拥塞、窗口
连接立刻 RST → 端口关闭/策略拒绝/应用踢人
本机连不上自己的服务 → 是否 listen、是否绑对地址
偶发连不上 → 半开连接、积压队列、端口耗尽
4.2 工具箱
| 工具 | 干什么 |
|---|---|
ss -lntup |
谁在监听?哪个进程? |
ss -ant |
TCP 连接状态分布 |
curl -v / 浏览器 Timing |
Connect 是否慢 |
tcpdump / Wireshark |
看 SYN 有没有回 SYN-ACK |
nc / telnet |
粗测端口通不通 |
4.3 实操一:看本机监听与连接(必做)
# 监听中的 TCP 端口与进程(Linux)
ss -lntp
# 当前 TCP 连接摘要
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn
你会见到 LISTEN / ESTABLISHED / TIME-WAIT 等状态------
TIME-WAIT 多不一定是事故,高并发短连接时很常见;真成问题再谈调优。
4.4 实操二:区分「IP 通」和「端口通」
# 换你要测的目标
ping -c 3 example.com
curl -vI --connect-timeout 5 https://example.com
| 现象 | 判断 |
|---|---|
| ping 失败 | 先网络层/禁 ICMP |
| ping 成功,curl 卡在 Connecting | 传输路径/443/防火墙嫌疑大 |
| 很快证书或 HTTP 错误 | TCP 多半已通,问题在上层 |
4.5 实操三:抓一次握手(进阶加分)
# 需要权限;另开终端访问 https 站点
sudo tcpdump -ni any -c 20 'tcp port 443 and (tcp[tcpflags] & (tcp-syn|tcp-ack) != 0)'
期望看到类似:SYN → SYN+ACK → ACK。
若只有 SYN 没有回包:路径丢了、或对端/中间策略丢弃。
flowchart TB
P[现象:连不上 / 很慢] --> A{ping IP?}
A -->|否| N[查网络/路由/链路]
A -->|是| B{端口能连?}
B -->|否| T[ss看监听 / 安全组 / tcpdump看SYN]
B -->|是| APP[查 TLS / HTTP / 业务]

4.6 故障速查清单(收藏)
| 现象 | 可能原因 | 先做什么 |
|---|---|---|
| Connection timed out | 丢弃/黑洞/未放行 | 安全组、tcpdump 看有无 SYN-ACK |
| Connection refused | 到达主机但端口无服务 | ss -lnt 是否 LISTEN |
| 大量重传 | 丢包、拥塞、劣质 Wi‑Fi | 换有线对比;看 RTT/丢包 |
| 服务端 SYN 队列溢出 | 突发连接打满 | 看半开连接、反压、扩容 |
| UDP 业务偶发失败 | 中间丢 UDP、NAT 超时 | 查防火墙是否只放 TCP |
本章小结
传输层:把数据交到「哪个程序」,并做可靠/实时取舍
端口是窗口号,五元组认出一条连接
UDP 平邮图快,TCP 挂号求稳,QUIC 想两头讨好
握手同步双方,窗口与拥塞决定能跑多欢
队头阻塞解释了为啥协议一直在升级
排障:ping 通只到主机,端口通不通用 ss/curl/tcpdump