第 58 章 TCP/IP 网络基础 (Sockets: Fundamentals of TCP/IP Networks)
核心结论
-
TCP/IP 四层模型:应用层 → 传输层(TCP/UDP)→ 网络层(IP)→ 数据链路层(driver/hardware);每层封装上一层数据。
-
internet 与 Internet:internet(小写 i)是网络的网络;Internet(大写 I)是全球 TCP/IP 网络;TCP/IP 1983 年随 4.2BSD 普及。
-
IP 协议:IPv4 32 位地址(点分十进制);IPv6 128 位地址(冒号十六进制);无连接、不可靠;MTU 分片(IPv4 ≤ 65535 字节,IPv6 jumbo 可更大)。
-
端口号:16 位整数;0-1023 是 well-known/privileged 端口(需 CAP_NET_BIND_SERVICE);1024-41951 是 registered;49152-65535 是 dynamic/ephemeral(Linux 实际可调
/proc/sys/net/ipv4/ip_local_port_range)。 -
UDP:传输层;加端口号 + 校验和;不可靠、连接无关、消息边界;应用层需自实现可靠;典型小消息低延迟(DNS、查询)。
-
TCP:传输层;可靠、双向、字节流;连接建立三次握手;segment + ACK + 重传 + 序列号;流控制(滑动窗口);拥塞控制(slow-start + congestion avoidance)。
-
特殊地址:127.0.0.1(IPv4 loopback,INADDR_LOOPBACK);0.0.0.0(INADDR_ANY,多宿主绑定所有接口);::1(IPv6 loopback);::(IPv6 wildcard)。
-
RFCs:标准定义在 RFC;IANA 维护端口分配;TCP/IP RFC 791(IP)、793(TCP)、768(UDP)、1122(Host Requirements)、2460(IPv6)。
|
本章主旨
本章是 Internet 域 socket(第 59 章)的前置——理解 TCP/IP 协议栈的关键概念。读者需要建立的核心心智模型:(1) IP 不可靠——丢包/乱序/重复由上层处理;(2) TCP 在 IP 之上加可靠性——三次握手、ACK、重传、序列号、滑动窗口、拥塞控制;(3) UDP 在 IP 之上几乎无增强——只是加端口和校验和;(4) 端口号标识主机内的应用;(5) IP 地址 + 端口 = socket 寻址。理解这些后才能看懂 connect/bind/listen 在网络层面的意义。 |
一、核心概念
本章围绕 6 个核心概念展开:协议分层、IP 层、IP 地址、端口号、UDP、TCP。
| 概念 | 定义 + 重要性 | 实现提示 |
|---|---|---|
TCP/IP 四层模型 |
应用层 → 传输层(TCP/UDP)→ 网络层(IP)→ 数据链路层;封装——每层把上层数据当 opaque,加自己的 header |
§58.2;图 58-2;TCP/IP 协议栈;每层「透明」地屏蔽下层细节;RFCs 定义各层 |
IP 层(IPv4/IPv6) |
IPv4 32 位地址(dotted-decimal);IPv6 128 位地址(colon-hex);无连接 + 不可靠;MTU 分片;header 20-60 字节;path MTU discovery(TCP) |
§58.4;IPv4 最小重组缓冲区 576 字节;IPv6 jumbogram 选项;ARP(IP→MAC);ICMP(错误/ping);IGMP(多播) |
IP 地址 |
IPv4:network ID + host ID(mask 划界);CIDR 标记如 204.152.189.0/24;IPv6:format prefix + 128 位;INADDR_ANY=0.0.0.0(多宿主);INADDR_LOOPBACK=127.0.0.1 |
§58.5;特殊地址:127.0.0.0/8 loopback;0.0.0.0 wildcard;IPv6 ::1 / ::;IPv4-mapped IPv6 ::ffff:x.x.x.x |
端口号 |
16 位整数标识主机内应用;0-1023 well-known/privileged(CAP_NET_BIND_SERVICE);1024-41951 registered;49152-65535 ephemeral/dynamic |
§58.6.1;Linux ephemeral 范围 |
UDP |
传输层;加端口号 + 校验和;不可靠、连接无关、消息边界;应用层需自实现可靠;避免 IP 分片(datagram ≤ 512 字节更安全) |
§58.6.2;UDP 校验和 IPv4 可选、IPv6 必选;TCP 校验和都必选;UDP 适合 DNS/查询/实时游戏/语音 |
TCP |
传输层;可靠 + 双向 + 字节流;三次握手连接;segment + 序列号 + ACK + 重传;流控制(滑动窗口);拥塞控制(slow-start + congestion avoidance) |
§58.6.3;ISN(初始序列号)非 0 防旧段混淆;SO_RCVBUF 调接收缓冲;delayed ACK 节省包;SACK 选项(RFC 2018) |
二、详细笔记
58.1 internet 与 Internet
What:internet(i 小写)是网络的网络——用 IP 协议统一寻址;Internet(I 大写)是全球 TCP/IP 网络。
Why:区分术语——internet 是抽象概念;Internet 是具体实例。
How:
| 概念 | 定义 | 示例 |
|---|---|---|
internetwork/internet |
多个 subnetwork 用路由器连接 |
公司内网(多个 LAN 互联) |
Internet |
全球 TCP/IP 网络 |
全球互联网 |
subnetwork/subnet |
internet 的一个子网 |
/24 子网 192.168.1.0/24 |
router |
跨 subnet 转发数据的主机 |
家用路由器 |
multihomed host |
多网络接口的主机 |
服务器双网卡 |
When:(1) 跨 subnet 通信——路由器;(2) 多宿主主机——需 bind INADDR_ANY 接所有接口数据。
Example:图 58-1——Network 1(wakatipu/wanaka/pukaki)通过 router(tekapo)连到 Network 2(rotoiti)。
58.2 TCP/IP 协议分层与封装
What:四层模型——应用层/传输层/网络层/数据链路层;每层加自己的 header 封装上层数据。
Why:分层让每层独立演化——TCP 可换实现,IP 可换版本,应用不受影响。
How:
| 层 | 协议 | 作用 |
|---|---|---|
应用层 |
HTTP/SSH/DNS/SMTP |
应用间协议;socket API |
传输层 |
TCP/UDP |
端口号 + 可靠/不可靠 |
网络层 |
IP(IPv4/IPv6) |
主机间路由;IP 地址 |
数据链路层 |
Ethernet/Wi-Fi/PPP |
物理链路;MAC 地址 |
封装过程:应用数据 → TCP header(端口/序列号/ACK/校验和)→ IP header(源/目的 IP)→ Frame header(源/目的 MAC)→ 物理传输。
When:(1) 应用 socket——TCP/UDP 选择(stream vs dgram);(2) 调试网络——tcpdump/wireshark 看每层 header;(3) 性能——分片/重组开销大,避免大 datagram。
Example:图 58-4——application data 装进 TCP segment → IP datagram → frame;每层加 header。
58.3 IP 层与 IP 地址
What:IP 层提供主机到主机的不可靠数据报服务;IP 地址标识主机。
Why:互联网的核心——统一寻址 + 路由。
How:
IPv4 地址格式:
* 32 位(4 字节)——点分十进制如 204.152.189.116
* 包含 network ID + host ID(用 mask 划界)
* CIDR 标记:204.152.189.0/24(24 位 network ID)
IPv6 地址格式:
* 128 位(16 字节)——冒号十六进制如 F000:0:0:0:0:0:A:1
* 简写:F000::A:1(连续零可用 :: 替代,仅一次)
特殊地址:
| 地址 | 含义 | 0.0.0.0(INADDR_ANY) |
|---|---|---|
wildcard;bind 时接所有接口 |
127.0.0.1(INADDR_LOOPBACK) |
loopback;数据不实际出本机 |
255.255.255.255 |
广播 |
::1 |
IPv6 loopback |
:: |
IPv6 wildcard(= 0::0) |
When:(1) bind server——INADDR_ANY 接所有接口;(2) connect localhost——127.0.0.1;(3) IPv4/IPv6 双栈——用 AF_INET6 + IPV6_V6ONLY 选项。
Example:struct sockaddr_in addr = { .sin_addr.s_addr = htonl(INADDR_ANY) }; 让服务器接所有接口的连接。
58.4 端口号
What:16 位整数标识主机内应用;TCP/UDP 各自独立。
Why:IP 标识主机,端口标识应用——IP+port = socket 寻址。
How:
| 范围 | 类型 | 说明 |
|---|---|---|
0-1023 |
well-known / privileged |
IANA 永久分配;Linux 需 CAP_NET_BIND_SERVICE |
1024-41951 |
registered |
IANA 注册但不强制 |
49152-65535 |
dynamic / private |
IANA 推荐的 ephemeral 范围 |
Linux 实际 ephemeral |
(可调) |
|
著名端口:22(SSH)、80(HTTP)、443(HTTPS)、53(DNS)。
When:(1) bind 80/443 等——需 root 或 CAP_NET_BIND_SERVICE;(2) 客户端 bind 0——内核分配 ephemeral;(3) 避免与已知服务冲突——选 registered 范围。
Example:echo 32768 60999 > /proc/sys/net/ipv4/ip_local_port_range 调 ephemeral 范围。
58.5 UDP
What:UDP = IP + 端口 + 校验和;不可靠、连接无关、消息边界。
Why:低延迟、小消息;不需可靠时比 TCP 简单。
How:
| 维度 | UDP | TCP |
|---|---|---|
连接 |
无连接(连接无关) |
面向连接(三次握手) |
可靠性 |
不可靠(丢包、乱序、重复) |
可靠(ACK + 重传 + 序列号) |
消息边界 |
保留 |
字节流(无边界) |
头部 |
8 字节 |
20-60 字节 |
校验和 |
IPv4 可选、IPv6 必选 |
都必选 |
流量控制 |
无 |
滑动窗口 |
拥塞控制 |
无 |
slow-start + congestion avoidance |
适用 |
DNS/查询/实时游戏/语音 |
HTTP/SSH/FTP/邮件 |
避免 IP 分片:UDP datagram ≤ 512 字节(更安全)或 ≤ 548 字节(IPv4 最小重组 576 - 8 UDP - 20 IP)。
When:(1) 小消息 + 不需可靠——UDP;(2) 实时性 > 可靠性——UDP(可丢包不能延迟);(3) 大数据传输——TCP。
Example:DNS 查询用 UDP 53 端口——查询/响应都小,丢包重试简单。
58.6 TCP
What:TCP = IP + 端口 + 可靠(ACK/重传/序列号)+ 流控 + 拥控。
Why:可靠数据传输的标准——HTTP/SSH/FTP/邮件。
How:
TCP 关键机制:
| 机制 | 作用 |
|---|---|
三次握手 |
建立连接(防旧段混淆;ISN 协商) |
序列号 |
每个字节一个序号——排序、去重、ACK |
ACK |
接收方确认收到——累计确认 |
重传 |
超时未 ACK 重传;动态调整 RTO |
流控制 |
滑动窗口——接收方通知可用缓冲 |
拥塞控制 |
slow-start(指数增长)+ congestion avoidance(线性增长) |
delayed ACK |
延迟 ~200ms 等待 piggyback 响应 |
TCP endpoint:内核为每端维护——send buffer、receive buffer、状态信息。
When:(1) 可靠数据传输——TCP;(2) 高吞吐——TCP 拥塞控制自动调节;(3) 低延迟不可丢——UDP 或 QUIC。
Example:典型 TCP 通信——client connect → 三次握手 → 双向读写 → close → 四次挥手。
58.7 关键 RFCs
What:TCP/IP 协议标准定义在 RFC 文档。
Why:需要准确理解协议时查 RFC。
How:
| RFC | 主题 | 年份 |
|---|---|---|
791 |
Internet Protocol(IPv4) |
1981 |
793 |
Transmission Control Protocol(TCP) |
1981 |
768 |
User Datagram Protocol(UDP) |
1980 |
1122 |
Host Requirements(修正早期 RFC) |
1989 |
1323 |
TCP Extensions for High Performance |
1992 |
2018 |
TCP Selective Acknowledgment (SACK) |
1996 |
2581 |
TCP Congestion Control |
1999 |
2460 |
Internet Protocol v6 (IPv6) |
1998 |
3493 |
Basic Socket Interface Extensions for IPv6 |
2003 |
4291 |
IP Version 6 Addressing Architecture |
2006 |
When:(1) 调试 TCP 问题——查 RFC 793/2581/2988;(2) 实现 IPv6——查 RFC 2460/3493/4291;(3) 协议详情——www.rfc-editor.org。
*Example`:TCP 三次握手在 RFC 793 §3.4;TIME_WAIT 在 RFC 793 §3.5;滑动窗口在 RFC 793 §3.7。
三、关键图表
|
非可视化条目(协议 / 地址 / 端口)
|
四、思维导图
mindmap
root((第 58 章 TCP/IP 基础))
协议分层
应用层 HTTP SSH
传输层 TCP UDP
网络层 IP
数据链路层 Ethernet
封装 各层 header
IP 协议
IPv4 32 位
IPv6 128 位
无连接 不可靠
分片 MTU
最小重组 576 1500
IP 地址
IPv4 点分十进制
IPv6 冒号十六进制
CIDR n 标记
INADDR_ANY wildcard
INADDR_LOOPBACK 127 0 0 1
端口号
16 位
0 1023 privileged
1024 41951 registered
49152 65535 ephemeral
22 80 443 著名
UDP
无连接
不可靠
消息边界
校验和 IPv4 可选 IPv6 必选
头部 8 字节
适合 DNS 查询
TCP
三次握手
可靠 ACK 重传
字节流
序列号
滑动窗口
拥塞控制
slow start
congestion avoidance
== 五、重点与易错点
. *IP 不可靠*——不保证到达/有序/不重复;应用层(UDP)或传输层(TCP)负责可靠性。
. *TCP 可靠 = ACK + 重传 + 序列号 + 流控 + 拥控*——这五件事加在一起才是「可靠」。
. *UDP 不保证可靠*——丢包/乱序/重复由应用处理;UDP 校验和 IPv4 可选、IPv6 必选。
. *IPv4 vs IPv6*——IPv4 32 位(40 亿地址,已枯竭);IPv6 128 位(3.4×10³⁸ 地址)。
. *端口号 TCP/UDP 独立*——TCP 80 和 UDP 80 是不同端口;同号通常同服务。
. *Privileged 端口 0-1023*——bind 需 CAP_NET_BIND_SERVICE(通常 root);防普通用户伪装知名服务。
. *bind 0 = 内核分配 ephemeral*——客户端不需要固定端口。
. *INADDR_ANY (0.0.0.0)*——服务器 bind 接所有接口;多宿主主机推荐。
. *127.0.0.1 loopback*——数据不实际出本机;测试本机服务方便;UNIX 域 socket 更快替代。
. *IPv4-mapped IPv6 ::ffff:x.x.x.x*——IPv6 socket 兼容 IPv4 通信。
. *TCP 三次握手*——SYN/SYN-ACK/ACK;ISN 协商防旧段混淆。
. *TCP 流控制 vs 拥塞控制*——流控是接收方(接收窗口);拥控是发送方(拥塞窗口);取 min 限制发送。
. *UDP datagram ≤ 512 字节*——避免 IP 分片;IPv4 最小重组 576 字节。
. *TCP segment 含 ACK*——支持 piggyback(delayed ACK 节省包)。
. *RFC 791/793/768/1122*——IPv4/TCP/UDP/Host Requirements;其他 RFC 在 RFC 1122 基础上扩展。
. *跨章衔接*:第 56 章 socket 总览;第 57 章 UNIX 域;第 59 章 Internet 域 socket 编程(基于本章概念);第 60 章 socket 服务器设计;第 61 章 socket 高级(TCP_NODELAY、SO_KEEPALIVE 等)。