欢迎光临
我们一直在努力

TCP/IP 协议栈实战 — 7 个实验详解

TCP/IP 协议栈实战 — 7 个实验详解

实验环境: 华为云 ECS 集群 ecs-76fc (4 × 8vCPU/16GiB, Ubuntu 24.04.4 LTS)

节点分配:

  • net-01: 1.92.94.82 / 192.168.0.228 (主实验节点)
  • net-02: 120.46.81.11 / 192.168.0.65 (对端节点)
  • net-03: 120.46.87.126 / 192.168.0.91 (辅助节点)
  • net-04: 120.46.214.92 / 192.168.0.251 (辅助节点)

内核版本: 6.8.0-106-generic | MTU: 1500 | 工具: tcpdump, traceroute, dig, nc, iperf3, arping, ethtool, nmap


实验架构总览

┌─────────────────────────────────────────┐
│ TCP/IP 协议栈 │
├─────────────────────────────────────────┤
应用层 │ DNS FTP HTTP Telnet SMTP/POP3│ ← 实验7
├─────────────────────────────────────────┤
传输层 │ TCP UDP │ ← 实验5,6
├─────────────────────────────────────────┤
网络层 │ IP ARP ICMP IGMP RARP │ ← 实验3,4
├─────────────────────────────────────────┤
链路层 │ 以太网 PPP SLIP MTU │ ← 实验2
├─────────────────────────────────────────┤
物理层 │ 双绞线 光纤 无线 │
└─────────────────────────────────────────┘

实验1: TCP/IP 简介
(IP地址/域名/MAC/端口/封装分用)


实验1: TCP/IP 简介

1.1 IP 地址 (IP Address)

IP 地址是网络层的核心标识,用于在网络上唯一标识一台主机。

IPv4 地址格式: 32 位二进制,点分十进制表示 (Dotted Decimal Notation)

192.168.0.228 → 11000000.10101000.00000000.11100100

实操 — 查看本机 IP 地址:

# 查看完整接口信息
$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether fa:16:3e:ed:45:29 brd ff:ff:ff:ff:ff:ff
altname enp0s3
altname ens3
inet 192.168.0.228/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0
valid_lft 315359577sec preferred_lft 315359577sec
inet6 fe80::f816:3eff:feed:4529/64 scope link
valid_lft forever preferred_lft forever

关键参数解释:

参数含义
BROADCAST 支持广播
MULTICAST 支持组播
UP,LOWER_UP 接口已启用且物理链路连通
mtu 1500 最大传输单元 1500 字节
inet 192.168.0.228/24 IPv4 地址,/24 为 CIDR 前缀长度
brd 192.168.0.255 广播地址
scope global 全局可路由地址
dynamic 通过 DHCP 动态获取
valid_lft 地址有效生存期 (秒)
inet6 fe80::… IPv6 链路本地地址 (Link-Local)

仅提取 IPv4 / IPv6:

$ ip -4 addr show eth0 | grep inet
inet 192.168.0.228/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0

$ ip -6 addr show eth0 | grep inet6
inet6 fe80::f816:3eff:feed:4529/64 scope link

1.2 域名 (Domain Name)

域名是 IP 地址的人类可读别名,通过 DNS (Domain Name System) 解析为 IP 地址。

实操 — DNS 解析:

# nslookup 查询
$ nslookup baidu.com
Server:127.0.0.53
Address:127.0.0.53#53

Non-authoritative answer:
Name:baidu.com
Address: 111.63.65.247
Name:baidu.com
Address: 110.242.74.102
Name:baidu.com
Address: 111.63.65.103
Name:baidu.com
Address: 124.237.177.164

# dig 简短输出
$ dig +short google.com
142.251.34.78

# DNS 反向解析 (PTR 记录)
$ dig -x 8.8.8.8 +short
dns.google.

DNS 解析配置:

$ cat /etc/resolv.conf
nameserver 127.0.0.53 # systemd-resolved 本地存根解析器
options edns0 trust-ad
search openstacklocal # 搜索域

注意: Ubuntu 24.04 使用 systemd-resolved 作为本地 DNS 存根,实际 DNS 请求由 127.0.0.53 转发到上游服务器。

1.3 MAC 地址 (Media Access Control Address)

MAC 地址是数据链路层的硬件地址,48 位 (6 字节),烧录在网卡中。

格式: fa:16:3e:ed:45:29 (十六进制,冒号分隔)

实操 — 查看 MAC 和 ARP 表:

# 查看 MAC 地址
$ ip link show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether fa:16:3e:ed:45:29 brd ff:ff:ff:ff:ff:ff

# ARP 表 — IP 与 MAC 的映射
$ ip neigh show
192.168.0.91 dev eth0 lladdr fa:16:3e:ed:45:a0 REACHABLE
192.168.0.251 dev eth0 lladdr fa:16:3e:ed:45:40 REACHABLE
192.168.0.65 dev eth0 lladdr fa:16:3e:ed:45:86 REACHABLE
192.168.0.1 dev eth0 lladdr fa:16:3e:2c:d7:71 REACHABLE

# 传统 arp 命令
$ arp -a
? (192.168.0.91) at fa:16:3e:ed:45:a0 [ether] on eth0
? (192.168.0.251) at fa:16:3e:ed:45:40 [ether] on eth0
? (192.168.0.65) at fa:16:3e:ed:45:86 [ether] on eth0
_gateway (192.168.0.1) at fa:16:3e:2c:d7:71 [ether] on eth0

ARP 状态说明:

状态含义
REACHABLE 可达,缓存有效
STALE 过期,需重新验证
DELAY 等待探测
FAILED 解析失败

华为云 MAC 特征: fa:16:3e 前缀是华为云虚拟化平台的 OUI (Organizationally Unique Identifier)。

1.4 端口号 (Port Number)

端口号标识主机上的具体进程/服务,范围 0~65535。

端口分类:

范围类别示例
0~1023 知名端口 (Well-Known) SSH:22, HTTP:80, DNS:53
1024~49151 注册端口 (Registered) MySQL:3306, Redis:6379
49152~65535 动态端口 (Ephemeral) 客户端临时端口

实操 — 端口查看:

# /etc/services 定义已知端口
$ head -20 /etc/services
tcpmux1/tcp# TCP port service multiplexer
echo7/tcp
echo7/udp
discard9/tcpsink null
...

# 当前监听端口
$ ss -tlnp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemdresolve",pid=486))
LISTEN 0 10 127.0.0.1:29338 0.0.0.0:* users:(("uniagentd",pid=5808))
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=5564))
LISTEN 0 4096 [::]:22 [::]:* users:(("sshd",pid=5564))

# 当前建立的连接
$ ss -tnp | head -10
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 2016 192.168.0.228:22 120.25.187.184:23273 users:(("sshd",pid=7747))
ESTAB 0 0 192.168.0.228:53374 100.125.12.110:33554 users:(("uniagentd",pid=5808))

1.5 封装和分用 (Encapsulation & Demultiplexing)

封装: 数据从应用层向下传递时,每层添加自己的协议头部。

分用: 接收方根据各层头部信息,将数据交给正确的协议处理。

发送端 (封装) 接收端 (分用)
┌──────────┐ ┌──────────┐
│ 应用数据 │ │ 应用数据 │
└────┬─────┘ └─────▲────┘
+TCP 头部 +TCP 头部
┌────┴─────┐ ┌─────┴────┐
│ TCP 报文 │ ──→ 端口号分用 ──→ │ TCP 报文 │
└────┬─────┘ └─────▲────┘
+IP 头部 +IP 头部
┌────┴─────┐ ┌─────┴────┐
│ IP 数据报│ ──→ 协议字段分用 ──→ │ IP 数据报│
└────┬─────┘ └─────▲────┘
+以太网帧头 +以太网帧头
┌────┴─────┐ ┌─────┴────┐
│ 以太网帧 │ ──→ EtherType分用 ──→ │ 以太网帧 │
└──────────┘ └──────────┘

实操 — tcpdump 抓包观察封装:

$ tcpdump -i eth0 -c 5 -nn -vv 'host 192.168.0.65'
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes

# ICMP Echo Request — 从 net-01 到 net-02
19:53:39.177970 IP (tos 0x0, ttl 64, id 26352, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.0.228 > 192.168.0.65: ICMP echo request, id 8078, seq 1, length 64

# ICMP Echo Reply — 从 net-02 回复
19:53:39.178128 IP (tos 0x0, ttl 64, id 40893, offset 0, flags [none], proto ICMP (1), length 84)
192.168.0.65 > 192.168.0.228: ICMP echo reply, id 8078, seq 1, length 64

IP 头部关键字段解读:

字段值含义
tos 0x0 Type of Service 服务类型,0 表示普通
ttl 64 Time To Live 生存时间,每经过路由器减1
id 26352 Identification 数据报标识,用于分片重组
flags [DF] Don’t Fragment 不允许分片
proto ICMP (1) Protocol 上层协议:1=ICMP, 6=TCP, 17=UDP
length 84 Total Length IP 数据报总长度(含头部)

实验2: 链路层介绍

2.1 以太网 (Ethernet)

以太网是最广泛使用的局域网技术,IEEE 802.3 标准。

实操 — 查看以太网接口信息:

$ ethtool eth0
Settings for eth0:
Supported ports: [ ]
Supported link modes: Not reported
Supported pause frame use: No
Supports auto-negotiation: No
Speed: Unknown!
Duplex: Unknown! (255)
Auto-negotiation: off
Port: Other
PHYAD: 0
Transceiver: internal
Link detected: yes

说明: 云服务器的虚拟网卡 (VirtIO) 不报告物理参数 (Speed/Duplex),但 Link detected: yes 表示链路正常。

以太网帧格式:

┌──────────┬──────────┬─────────┬──────────────────┬─────────┐
│ 目的MAC │ 源MAC │ 类型 │ 数据 (46~1500B) │ FCS │
│ 6字节 │ 6字节 │ 2字节 │ │ 4字节 │
└──────────┴──────────┴─────────┴──────────────────┴─────────┘
↑ 帧头 ↑ 数据区 ↑ 帧尾
EtherType: 0x0800=IPv4, 0x0806=ARP, 0x86DD=IPv6

实操 — 抓取以太网帧 (显示链路层头):

$ tcpdump -i eth0 -c 3 -e -nn
19:54:11.957016 fa:16:3e:ed:45:29 > fa:16:3e:2c:d7:71, ethertype IPv4 (0x0800), length 262: 192.168.0.228.22 > 120.25.187.184.44026: Flags [P.]
19:54:11.970786 fa:16:3e:2c:d7:71 > fa:16:3e:ed:45:29, ethertype IPv4 (0x0800), length 56: 114.116.222.26.50753 > 192.168.0.228.32048: Flags [S]
19:54:11.970788 fa:16:3e:ed:45:29 > fa:16:3e:2c:d7:71, ethertype IPv4 (0x0800), length 54: 192.168.0.228.32048 > 114.116.222.26.50753: Flags [R.]

-e 选项显示源/目的 MAC 地址和 EtherType。

2.2 控制帧的传输 — ARP 协议

ARP (Address Resolution Protocol) 将 IP 地址解析为 MAC 地址。

实操 — ARP 请求/应答抓包:

# 清空 ARP 缓存 → 触发新的 ARP 请求
$ ip neigh del 192.168.0.65 dev eth0
$ ping -c 1 192.168.0.65

# 同时抓取 ARP 帧
$ tcpdump -i eth0 -c 4 -nn -vv 'arp'
19:55:06.714024 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.0.199 tell 192.168.0.228, length 28
19:55:06.723634 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.0.65 tell 192.168.0.228, length 28
19:55:06.723668 ARP, Ethernet (len 6), IPv4 (len 4), Reply 192.168.0.65 is-at fa:16:3e:ed:45:86, length 28

ARP 工作流程:

net-01 (192.168.0.228) net-02 (192.168.0.65)
│ │
│── ARP Request (广播) ──────────────→ │ "谁有 192.168.0.65?告诉 192.168.0.228"
│ │
│←── ARP Reply (单播) ─────────────── │ "192.168.0.65 的 MAC 是 fa:16:3e:ed:45:86"
│ │
│── IP 数据报 (单播) ────────────────→ │ 现在可以直接发送

使用 arping 发送 ARP 请求:

$ arping -c 3 -I eth0 192.168.0.65
ARPING 192.168.0.65
58 bytes from fa:16:3e:ed:45:86 (192.168.0.65): index=0 time=48.682 usec
58 bytes from fa:16:3e:ed:45:86 (192.168.0.65): index=1 time=47.162 usec
58 bytes from fa:16:3e:ed:45:86 (192.168.0.65): index=2 time=56.612 usec
192.168.0.65 statistics —
3 packets transmitted, 3 packets received, 0% unanswered (0 extra)
rtt min/avg/max/std-dev = 0.047/0.051/0.057/0.004 ms

ARP 缓存参数:

$ cat /proc/sys/net/ipv4/neigh/eth0/base_reachable_time_ms
30000 # ARP 条目可达状态持续 30 秒

2.3 MTU (Maximum Transmission Unit)

MTU 是数据链路层一次能传输的最大数据量。

实操 — 查看和修改 MTU:

# 查看当前 MTU
$ ip link show dev eth0 | grep mtu
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP

# 修改 MTU 为 1400
$ ip link set dev eth0 mtu 1400
$ ip link show dev eth0 | grep mtu
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc mq state UP

# 恢复 MTU
$ ip link set dev eth0 mtu 1500

常见 MTU 值:

网络MTU
以太网 1500
PPPoE 1492
GRE 隧道 1476
IPSec 1420
Jumbo Frame 9000

2.4 PPP 与 SLIP 对比

特性SLIP (Serial Line IP)PPP (Point-to-Point Protocol)
标准 RFC 1055 (非正式) RFC 1661
错误检测 FCS (Frame Check Sequence)
协议复用 仅 IP 多协议 (IP, IPX, AppleTalk)
认证 PAP, CHAP
地址协商 IPCP
压缩 CSLIP (Van Jacobson) CCP (多种压缩算法)
当前状态 已淘汰 仍用于宽带接入

# Linux PPP 守护进程
$ ls -la /usr/sbin/pppd
-rwsr-xr– 1 root dip 420416 Apr 4 2024 /usr/sbin/pppd

$ pppd –version
pppd version 2.4.9

2.5 以太网帧统计

$ ip -s link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP
link/ether fa:16:3e:ed:45:29 brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped missed mcast
79617857 85208 0 0 0 0
TX: bytes packets errors dropped carrier collsns
3067783 46947 0 0 0 0

统计项含义
RX bytes/packets 接收字节数/包数
RX errors 接收错误
RX dropped 接收丢弃
TX carrier 载波错误
TX collsns 碰撞次数 (以太网 CSMA/CD)

实验3: IP 网际协议

3.1 IP 数据报头部

IP 数据报是网络层的数据传输单元,头部最小 20 字节。

0 16 31
┌────────┬────────┬─────────────────────────────┐
│ 版本(4)│头部长度│ 服务类型 (TOS) │ 总长度 │
├────────┴────────┼─────────────────────────────┤
│ 标识 (ID) │标志│ 片偏移 │
├─────────────────┼─────────────────────────────┤
│ 生存时间(TTL) │ 协议 (Protocol) │ 头部校验和 │
├─────────────────┴─────────────────────────────┤
│ 源 IP 地址 │
├────────────────────────────────────────────────┤
│ 目的 IP 地址 │
├────────────────────────────────────────────────┤
│ 选项 (可选, 0~40字节) │
└────────────────────────────────────────────────┘

实操 — 抓取 IP 数据报头部:

$ tcpdump -i eth0 -c 2 -nn -vvv 'host 192.168.0.65 and icmp'
19:54:40.744616 IP (tos 0x0, ttl 64, id 28931, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.0.228 > 192.168.0.65: ICMP echo request, id 8624, seq 1, length 64
19:54:40.744789 IP (tos 0x0, ttl 64, id 6505, offset 0, flags [none], proto ICMP (1), length 84)
192.168.0.65 > 192.168.0.228: ICMP echo reply, id 8624, seq 1, length 64

头部字段与抓包对照:

字段抓包值含义
TOS 0x0 服务类型,0=Best Effort
TTL 64 Linux 默认 TTL=64,每经路由器减1
ID 28931 数据报标识
Flags [DF] Don’t Fragment — 不允许分片
Protocol ICMP (1) 上层协议号
Length 84 IP 总长度 (20B 头部 + 64B ICMP)

3.2 IP 地址分类

类别首字节范围网络位/主机位默认掩码私有地址范围
A 类 1~126 8/24 255.0.0.0 10.0.0.0/8
B 类 128~191 16/16 255.255.0.0 172.16.0.0/12
C 类 192~223 24/8 255.255.255.0 192.168.0.0/16
D 类 224~239 组播地址
E 类 240~255 保留/实验

本实验地址 192.168.0.228 属于 C 类私有地址。

3.3 子网划分

实操 — ipcalc 子网计算:

# /24 子网 (默认)
$ ipcalc 192.168.0.228/24
Address: 192.168.0.228 11000000.10101000.00000000. 11100100
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000
Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111
=>
Network: 192.168.0.0/24 11000000.10101000.00000000. 00000000
HostMin: 192.168.0.1 11000000.10101000.00000000. 00000001
HostMax: 192.168.0.254 11000000.10101000.00000000. 11111110
Broadcast: 192.168.0.255 11000000.10101000.00000000. 11111111
Hosts/Net: 254 Class C, Private Internet

# /28 子网 (更细划分)
$ ipcalc 192.168.0.228/28
Address: 192.168.0.228 11000000.10101000.00000000.1110 0100
Netmask: 255.255.255.240 = 28 11111111.11111111.11111111.1111 0000
Wildcard: 0.0.0.15 00000000.00000000.00000000.0000 1111
=>
Network: 192.168.0.224/28 11000000.10101000.00000000.1110 0000
HostMin: 192.168.0.225
HostMax: 192.168.0.238
Broadcast: 192.168.0.239
Hosts/Net: 14

子网划分对照表:

CIDR子网掩码可用主机数子网数 (从/24划分)
/24 255.255.255.0 254 1
/25 255.255.255.128 126 2
/26 255.255.255.192 62 4
/27 255.255.255.224 30 8
/28 255.255.255.240 14 16
/29 255.255.255.248 6 32
/30 255.255.255.252 2 64

3.4 IP 路由选择

实操 — 路由表查看:

$ ip route show
default via 192.168.0.1 dev eth0 proto dhcp src 192.168.0.228 metric 100
169.254.169.254 via 192.168.0.1 dev eth0 proto dhcp src 192.168.0.228 metric 100
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.228 metric 100

路由含义
default via 192.168.0.1 默认网关,未知目的地发往此
169.254.169.254 云实例元数据服务 (华为云)
192.168.0.0/24 dev eth0 同子网直连路由

路由查找示例:

# 同子网 → 直达
$ ip route get 192.168.0.65
192.168.0.65 dev eth0 src 192.168.0.228 uid 0
cache

# 外部地址 → 经网关
$ ip route get 8.8.8.8
8.8.8.8 via 192.168.0.1 dev eth0 src 192.168.0.228 uid 0
cache

3.5 NAT 技术

NAT (Network Address Translation) 将私有 IP 转换为公网 IP,解决 IPv4 地址不足。

NAT 类型:

类型英文说明
SNAT Source NAT 修改源地址 (出方向)
DNAT Destination NAT 修改目的地址 (入方向, 端口转发)
MASQUERADE 动态 SNAT (动态公网 IP)

实操 — iptables NAT 规则:

# 当前 NAT 规则 (空)
$ iptables -t nat -L -n -v
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)

# SNAT 示例命令
# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE

# IP 转发开关 (0=关闭, 1=开启)
$ cat /proc/sys/net/ipv4/ip_forward
0

注意: 云服务器的 NAT 由云平台虚拟网络 (VPC) 完成,实例内无需配置。

3.6 IP 的未来 — IPv6

# IPv6 地址 (仅链路本地)
$ ip -6 addr show eth0
inet6 fe80::f816:3eff:feed:4529/64 scope link

# IPv6 路由
$ ip -6 route show
fe80::/64 dev eth0 proto kernel metric 256 pref medium

# IPv6 组播测试
$ ping6 -c 2 -W 3 ff02::1%eth0
64 bytes from fe80::f816:3eff:feed:4529%eth0: icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from fe80::f816:3eff:feed:4529%eth0: icmp_seq=2 ttl=64 time=0.015 ms

IPv4 vs IPv6 头部对比:

特性IPv4IPv6
头部长度 20~60 字节 (可变) 40 字节 (固定)
地址长度 32 位 128 位
校验和 无 (交由链路层/传输层)
分片 路由器可分片 仅源端分片
选项 头部选项字段 扩展头部
广播 无 (用组播替代)
配置 手动/DHCP SLAAC/DHCPv6

实验4: 网络层其它协议

4.1 ARP 协议详解

ARP (Address Resolution Protocol, RFC 826) 将网络层 IP 地址映射为链路层 MAC 地址。

ARP 报文格式:

┌────────────────┬────────────────┬──────────┬──────────┐
│ 硬件类型(16bit) │ 协议类型(16bit) │ 硬件地址 │ 协议地址 │
│ 1=以太网 │ 0x0800=IPv4 │ 长度(8b) │ 长度(8b) │
├────────────────┴────────────────┼──────────┴──────────┤
│ 操作码(16bit): 1=Request, 2=Reply │ │
├──────────────────────────────────┤ │
│ 发送方硬件地址 (6字节) │ │
├──────────────────────────────────┤ │
│ 发送方协议地址 (4字节) │ │
├──────────────────────────────────┤ │
│ 目标硬件地址 (6字节) │ │
├──────────────────────────────────┤ │
│ 目标协议地址 (4字节) │ │
└──────────────────────────────────┘

实操 — ARP 请求/应答抓包 (已在实验2中展示)

4.2 RARP 协议

RARP (Reverse ARP, RFC 903) 是 ARP 的逆操作:已知 MAC 地址,查询 IP 地址。

当前状态: RARP 已被 BOOTP 和 DHCP 取代,现代系统不再使用。

4.3 ICMP 协议

ICMP (Internet Control Message Protocol, RFC 792) 用于传递错误信息和控制消息。

ICMP 报文类型:

Type名称用途
0 Echo Reply ping 回复
3 Destination Unreachable 目的不可达
5 Redirect 路由重定向
8 Echo Request ping 请求
11 Time Exceeded TTL 耗尽 (traceroute)

实操 — 抓取 ICMP Destination Unreachable:

$ tcpdump -i eth0 -c 6 -nn -vv 'icmp'
# UDP 端口不可达 (Type 3, Code 3)
19:55:06.024910 IP (tos 0xc0, ttl 64, id 15932, offset 0, flags [none], proto ICMP (1), length 88)
192.168.0.65 > 192.168.0.228: ICMP 192.168.0.65 udp port 33434 unreachable, length 68
IP (tos 0x0, ttl 1, id 51375, offset 0, flags [none], proto UDP (17), length 60)
192.168.0.228.51997 > 192.168.0.65.33434: [udp sum ok] UDP, length 32

注意: tos 0xc0 表示 ICMP 错误消息,优先级高于普通数据。

4.4 ping 程序

ping 使用 ICMP Echo Request (Type 8) / Echo Reply (Type 0) 测试连通性。

实操 — ping 各种用法:

# 普通 ping
$ ping -c 3 192.168.0.65
PING 192.168.0.65 (192.168.0.65) 56(84) bytes of data.
64 bytes from 192.168.0.65: icmp_seq=1 ttl=64 time=0.169 ms
64 bytes from 192.168.0.65: icmp_seq=2 ttl=64 time=0.137 ms
64 bytes from 192.168.0.65: icmp_seq=3 ttl=64 time=0.067 ms
192.168.0.65 ping statistics —
3 packets transmitted, 3 received, 0% packet loss, time 2024ms
rtt min/avg/max/mdev = 0.067/0.124/0.169/0.042 ms

# 指定包大小 ping
$ ping -c 3 -s 1000 192.168.0.65
PING 192.168.0.65 (192.168.0.65) 1000(1028) bytes of data.
1008 bytes from 192.168.0.65: icmp_seq=1 ttl=64 time=0.158 ms
1008 bytes from 192.168.0.65: icmp_seq=2 ttl=64 time=0.131 ms
1008 bytes from 192.168.0.65: icmp_seq=3 ttl=64 time=0.067 ms

# 记录路由 ping (-R 选项, 利用 IP 头部 Record Route 选项)
$ ping -c 3 -R 192.168.0.65
64 bytes from 192.168.0.65: icmp_seq=1 ttl=64 time=0.166 ms
RR: 192.168.0.228
192.168.0.65
192.168.0.65
192.168.0.228

ping 参数说明:

参数含义
-c N 发送 N 个包后停止
-s N 指定 ICMP 数据长度
-R 记录路由 (IP Record Route 选项)
-W N 超时等待 N 秒
-i N 发送间隔 N 秒

4.5 traceroute 程序

traceroute 利用 IP TTL 和 ICMP Time Exceeded 追踪路由路径。

原理: 发送 TTL=1 的数据报 → 第一跳路由器返回 ICMP Time Exceeded → 依次递增 TTL。

实操:

# 同子网 (1 跳)
$ traceroute -n 192.168.0.65
traceroute to 192.168.0.65 (192.168.0.65), 30 hops max, 60 byte packets
1 192.168.0.65 0.143 ms 0.144 ms *

# 公网路由追踪
$ traceroute -n -m 10 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 10 hops max, 60 byte packets
1 * * *
2 * * *
3 * * *
4 * * *
5 11.94.132.13 2.800 ms 11.94.12.203 1.780 ms 11.94.132.243 2.130 ms
6 * * *
7 172.16.229.86 1.465 ms 1.421 ms 172.16.230.30 1.989 ms
8 106.38.244.125 2.958 ms 2.142 ms 106.38.244.113 2.334 ms
9 * * *
10 * * *

* * * 表示该跳路由器不响应 ICMP 或被防火墙过滤。

4.6 IGMP 协议

IGMP (Internet Group Management Protocol) 管理主机组播组成员关系。

# 查看当前组播组
$ cat /proc/net/igmp
IdxDevice : Count QuerierGroup Users TimerReporter
1lo : 1 V3
010000E0 1 0:000000000
2eth0 : 1 V3
010000E0 1 0:000000000

010000E0 是 224.0.0.1 (所有主机组) 的小端序表示。内核运行 IGMPv3。

IGMP 版本对比:

版本RFC特性
IGMPv1 RFC 1112 基本查询/报告
IGMPv2 RFC 2236 增加离组消息 (Leave Group)
IGMPv3 RFC 3376 源特定组播 (SSM)

实验5: 传输层 UDP 协议

5.1 传输层协议概述

传输层提供端到端 (End-to-End) 通信,主要协议:

特性UDPTCP
连接方式 无连接 面向连接
可靠性 不可靠 可靠
顺序性 不保证 保证
流量控制 有 (滑动窗口)
拥塞控制
头部大小 8 字节 20~60 字节
传输效率 较低
适用场景 DNS/视频/游戏 HTTP/SSH/邮件

5.2 端口 (Port)

传输层通过端口号区分同一主机上的不同应用进程。

5.3 UDP 报文格式

┌──────────────────┬──────────────────┐
│ 源端口 (16bit) │ 目的端口 (16bit) │
├──────────────────┼──────────────────┤
│ 长度 (16bit) │ 校验和 (16bit) │
├──────────────────┴──────────────────┤
│ 数据 │
└─────────────────────────────────────┘
头部仅 8 字节!

5.4 UDP 通信实操

net-02 启动 UDP 服务端:

$ nc -u -l -p 9999 > /tmp/udp_recv.txt &
$ ss -ulnp | grep 9999
UNCONN 0 0 0.0.0.0:9999 0.0.0.0:* users:(("nc",pid=8082,fd=3))

net-01 发送 UDP 数据:

$ echo 'Hello UDP from net-01' | nc -u -w 2 192.168.0.65 9999
$ echo '第二条消息' | nc -u -w 2 192.168.0.65 9999
$ echo '第三条消息-测试' | nc -u -w 2 192.168.0.65 9999

tcpdump 抓取 UDP 报文:

$ tcpdump -i eth0 -c 4 -nn -vvv 'udp and host 192.168.0.65'
19:56:05.217099 IP (tos 0x0, ttl 64, id 61604, offset 0, flags [DF], proto UDP (17), length 44)
192.168.0.228.52299 > 192.168.0.65.9999: [bad udp cksum 0x829f –> 0xfc2a!] UDP, length 16
19:56:05.217873 IP (tos 0x0, ttl 64, id 6139, offset 0, flags [DF], proto UDP (17), length 40)
192.168.0.228.59254 > 192.168.0.65.9999: [bad udp cksum 0x829b –> 0x3e13!] UDP, length 12

bad udp cksum: 云服务器通常关闭 TX checksum offloading,导致 tcpdump 在本机抓包时看到校验和不匹配,实际发送时由网卡硬件计算正确的校验和。

5.5 UDP 带宽测试 (iperf3)

# 服务端
$ iperf3 -s -p 5201

# 客户端 (UDP, 10Mbps, 包长 1400)
$ iperf3 -c 127.0.0.1 -u -b 10M -l 1400 -t 3
Connecting to host 127.0.0.1, port 5201
[ 5] local 127.0.0.1 port 48538 connected to 127.0.0.1 port 5201
[ ID] Interval Transfer Bitrate Total Datagrams
[ 5] 0.00-1.00 sec 1.19 MBytes 10.0 Mbits/sec 893
[ 5] 1.00-2.00 sec 1.19 MBytes 9.99 Mbits/sec 892
[ 5] 2.00-3.00 sec 1.19 MBytes 10.0 Mbits/sec 893
– – – – – – – – – – – – – – – – – – – – – – – – –
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-3.00 sec 3.58 MBytes 10.0 Mbits/sec 0.000 ms 0/2678 (0%) sender
[ 5] 0.00-3.00 sec 3.58 MBytes 10.0 Mbits/sec 0.000 ms 0/2678 (0%) receiver

iperf3 UDP 参数说明:

参数含义
-u 使用 UDP 模式
-b 10M 带宽限制 10 Mbps
-l 1400 包长 1400 字节
-t 3 测试时长 3 秒
Jitter 抖动 (延迟方差)
Lost/Total 丢包率

实验6: 传输层 TCP 协议

6.1 TCP 报文段结构

0 16 31
┌────────────────┬────────────────────────────────┐
│ 源端口 │ 目的端口 │
├────────────────┴────────────────────────────────┤
│ 序号 (Sequence Number) │
├─────────────────────────────────────────────────┤
│ 确认号 (Acknowledgment Number) │
├──────┬─────────┬────────────────────────────────┤
│数据偏移│ 保留 │ U A P R S F │ 窗口大小 │
│(4bit) │(6bit)│ R C S S Y I │ (Window Size) │
│ │ │ G K H I N N │ │
├────────────────┼────────────────────────────────┤
│ 校验和 │ 紧急指针 │
├────────────────┴────────────────────────────────┤
│ 选项 (0~40字节) │
├─────────────────────────────────────────────────┤
│ 数据 │
└─────────────────────────────────────────────────┘

TCP Flags:
URG (0x20) = 紧急指针有效
ACK (0x10) = 确认号有效
PSH (0x08) = 接收方应尽快交给应用
RST (0x04) = 重置连接
SYN (0x02) = 同步序号
FIN (0x01) = 发送方完成

6.2 连接的建立 — 三次握手 (Three-Way Handshake)

客户端 (net-01) 服务端 (net-02)
192.168.0.228:38630 192.168.0.65:8888
│ │
│── SYN ─────────────────────────→ │ ① 客户端发送 SYN
│ seq=1176426314 │
│ │
│←── SYN+ACK ───────────────────── │ ② 服务端回复 SYN+ACK
│ seq=3202256481, ack=1176426315 │
│ │
│── ACK ─────────────────────────→ │ ③ 客户端确认 ACK
│ seq=1176426315, ack=3202256482 │
│ │
│═══ 连接建立,开始传输数据 ═════════│

实操 — tcpdump 抓取三次握手:

$ tcpdump -i eth0 -c 10 -nn -S -vvv 'tcp and host 192.168.0.65 and port 8888'

# ① SYN (客户端 → 服务端)
19:57:03.030397 IP ... 192.168.0.228.38630 > 192.168.0.65.8888:
Flags [S], seq 1176426314, win 64240,
options [mss 1460,sackOK,TS val 3032363684 ecr 0,nop,wscale 7], length 0

# ② SYN+ACK (服务端 → 客户端)
19:57:03.030530 IP ... 192.168.0.65.8888 > 192.168.0.228.38630:
Flags [S.], seq 3202256481, ack 1176426315, win 65160,
options [mss 1460,sackOK,TS val 567514268 ecr 3032363684,nop,wscale 7], length 0

# ③ ACK (客户端 → 服务端)
19:57:03.030539 IP ... 192.168.0.228.38630 > 192.168.0.65.8888:
Flags [.], seq 1176426315, ack 3202256482, win 502,
options [nop,nop,TS val 3032363685 ecr 567514268], length 0

TCP 选项解读:

选项含义
mss 1460 最大报文段长度 (Maximum Segment Size)
sackOK 支持选择性确认 (Selective Acknowledgment)
TS val/ecr 时间戳 (Timestamps),用于 RTT 计算和 PAWS
wscale 7 窗口扩大因子 2^7=128,窗口最大 64240×128≈8MB

6.3 连接的释放 — 四次挥手 (Four-Way Handshake)

客户端 (net-01) 服务端 (net-02)
│ │
│── FIN+ACK ────────────────────→ │ ① 客户端请求关闭
│ seq=1176426337, ack=3202256482 │
│ │
│←── FIN+ACK ──────────────────── │ ② 服务端也请求关闭
│ seq=3202256482, ack=1176426338 │
│ │
│── ACK ─────────────────────────→ │ ③ 客户端确认
│ seq=1176426338, ack=3202256483 │
│ │
│ (TIME_WAIT 2MSL) │

实操 — tcpdump 抓取四次挥手:

# ① FIN+ACK (客户端主动关闭)
19:57:06.033577 IP ... 192.168.0.228.38630 > 192.168.0.65.8888:
Flags [F.], seq 1176426337, ack 3202256482, win 502, length 0

# ② FIN+ACK (服务端同时关闭)
19:57:06.033724 IP ... 192.168.0.65.8888 > 192.168.0.228.38630:
Flags [F.], seq 3202256482, ack 1176426338, win 509, length 0

# ③ ACK (客户端最终确认)
19:57:06.033727 IP ... 192.168.0.228.38630 > 192.168.0.65.8888:
Flags [.], seq 1176426338, ack 3202256483, win 502, length 0

注意: 本次抓包显示的是"同时关闭" (Simultaneous Close),因为 nc 服务端在接收完数据后也立即关闭了连接。

6.4 TCP 可靠传输的实现

TCP 通过以下机制实现可靠传输:

  • 序号和确认号: 每个字节有序号,接收方确认已收到的数据
  • 超时重传: 发送方未收到 ACK 则重传
  • 校验和: 检测数据传输错误
  • 流量控制: 滑动窗口 (Sliding Window)
  • 拥塞控制: 慢启动、拥塞避免、快重传、快恢复
  • 6.5 超时重传

    # TCP 统计信息
    $ cat /proc/net/snmp | grep -A1 Tcp
    Tcp:
    162 active connection openings
    72 passive connection openings
    32 failed connection attempts
    39 connection resets received
    5 connections established
    128041 segments received
    123841 segments sent out
    51 segments retransmitted ← 重传了 51 个报文段
    1 bad segments received
    107259 resets sent

    6.6 连续 ARQ 协议

    ARQ (Automatic Repeat reQuest) 是 TCP 可靠传输的核心:

    ARQ 类型机制效率
    停止等待 ARQ 发一个等一个 ACK
    回退 N 步 (GBN) 连续发送,出错回退到出错点
    选择重传 (SR) 只重传出错的帧

    TCP 使用 选择重传 + 累积确认 的混合策略,通过 SACK 选项实现。

    6.7 流量控制和拥塞控制

    流量控制 (Flow Control): 接收方通过窗口大小 (Window Size) 限制发送方速率,防止接收方缓冲区溢出。

    拥塞控制 (Congestion Control): 发送方根据网络拥塞程度调整发送速率。

    TCP 拥塞控制算法:

    $ sysctl net.ipv4.tcp_available_congestion_control
    net.ipv4.tcp_available_congestion_control = reno cubic

    $ sysctl net.ipv4.tcp_congestion_control
    net.ipv4.tcp_congestion_control = cubic ← 当前使用 CUBIC

    算法特点
    Reno 经典算法,AIMD (加法增/乘法减)
    CUBIC Linux 默认,适合高带宽长肥网络
    BBR Google 提出,基于带宽和 RTT 模型

    拥塞控制四个阶段:

    慢启动阈值 (ssthresh)

    慢启动 │ 拥塞避免
    (指数增长) │ (线性增长)
    ╱ │ ╱
    ╱ │ ╱
    ╱ │ ╱ ───────→ 时间
    │╲
    │ ╲ 快恢复
    │ ╲ (重传后线性)
    │ ╲

    6.8 TCP 内核参数

    $ sysctl net.ipv4.tcp_syn_retries # SYN 重试次数: 6
    $ sysctl net.ipv4.tcp_synack_retries # SYN+ACK 重试次数: 5
    $ sysctl net.ipv4.tcp_fin_timeout # FIN_WAIT_2 超时: 60秒
    $ sysctl net.ipv4.tcp_keepalive_time # 保活探测间隔: 7200秒 (2小时)
    $ sysctl net.ipv4.tcp_keepalive_probes # 保活探测次数: 9

    TCP 连接统计:

    $ ss -s
    Total: 186
    TCP: 12 (estab 5, closed 1, orphaned 0, timewait 1)

    Transport Total IP IPv6
    RAW 0 0 0
    UDP 5 4 1
    TCP 11 10 1
    INET 16 14 2
    FRAG 0 0 0


    实验7: 应用层协议

    7.1 DNS 协议

    DNS (Domain Name System, RFC 1035) 是互联网的"电话簿",将域名解析为 IP 地址。

    DNS 记录类型:

    类型名称用途
    A Address 域名 → IPv4
    AAAA IPv6 Address 域名 → IPv6
    CNAME Canonical Name 域名别名
    MX Mail Exchange 邮件服务器
    NS Name Server DNS 服务器
    TXT Text 文本信息 (SPF/DKIM)
    PTR Pointer IP → 域名 (反向解析)

    实操 — DNS 查询:

    # A 记录
    $ dig baidu.com A +noall +answer
    baidu.com.449INA110.242.74.102
    baidu.com.449INA111.63.65.103
    baidu.com.449INA111.63.65.247
    baidu.com.449INA124.237.177.164

    # CNAME 记录
    $ dig www.baidu.com CNAME +noall +answer
    www.baidu.com.654INCNAMEwww.a.shifen.com.

    # MX 记录
    $ dig qq.com MX +noall +answer
    qq.com.4495INMX30 mx1.qq.com.
    qq.com.4495INMX20 mx2.qq.com.
    qq.com.4495INMX10 mx3.qq.com.

    # NS 记录
    $ dig baidu.com NS +noall +answer
    baidu.com.86400INNSdns.baidu.com.
    baidu.com.86400INNSns2.baidu.com.
    baidu.com.86400INNSns3.baidu.com.
    baidu.com.86400INNSns4.baidu.com.
    baidu.com.86400INNSns7.baidu.com.

    # TXT 记录
    $ dig baidu.com TXT +noall +answer
    baidu.com.7200INTXT"v=spf1 include:spf1.baidu.com include:spf2.baidu.com include:spf3.baidu.com include:spf4.baidu.com -all"

    DNS 解析过程 (递归查询):

    客户端 → 本地 DNS → 根域名服务器 → 顶级域 (.com) → 权威 DNS (baidu.com)
    ↑_____________________________________________|
    返回最终 IP 地址

    7.2 FTP 协议

    FTP (File Transfer Protocol, RFC 959) 用于文件传输,使用两个连接:

    连接端口用途
    控制连接 21/tcp 传输 FTP 命令
    数据连接 20/tcp (主动) / 随机 (被动) 传输文件数据

    实操 — FTP 匿名连接:

    $ curl -v ftp://ftp.gnu.org/
    * Connected to ftp.gnu.org (209.51.188.20) port 21
    < 220 GNU FTP server ready.
    > USER anonymous
    < 230-NOTICE (Updated October 15 2021):
    < 230-If you maintain scripts used to access ftp.gnu.org over FTP,
    < 230-we strongly encourage you to change them to use HTTPS instead.

    FTP 主动/被动模式:

    主动模式 (PORT): 被动模式 (PASV):
    客户端 ──── 控制连接(21) ────→ 服务器 客户端 ──── 控制连接(21) ────→ 服务器
    服务器 ──── 数据连接(20) ────→ 客户端 客户端 ──── 数据连接(随机) ────→ 服务器
    ↑ 服务器主动连客户端 ↑ 客户端主动连服务器
    ✗ 防火墙可能阻止 ✓ 防火墙友好

    7.3 HTTP 协议

    HTTP (HyperText Transfer Protocol) 是 Web 的基础协议。

    实操 — HTTP GET 请求:

    $ curl -sv http://httpbin.org/get
    > GET /get HTTP/1.1
    > Host: httpbin.org
    > User-Agent: curl/8.5.0
    > Accept: */*
    >
    < HTTP/1.1 503 Service Temporarily Unavailable
    < Server: awselb/2.0
    < Content-Type: text/html
    < Content-Length: 162

    HTTP 请求方法:

    方法用途
    GET 获取资源
    POST 提交数据
    PUT 更新资源
    DELETE 删除资源
    HEAD 获取响应头
    OPTIONS 查询支持的方法

    HTTP 状态码分类:

    范围类别常见状态码
    1xx 信息 100 Continue
    2xx 成功 200 OK, 201 Created
    3xx 重定向 301 永久重定向, 302 临时重定向
    4xx 客户端错误 400 Bad Request, 404 Not Found
    5xx 服务器错误 500 Internal Server Error, 503 Service Unavailable

    7.4 Telnet 协议

    Telnet (RFC 854) 是远程终端协议,现已基本被 SSH 取代,但可用于手动构造协议请求。

    实操 — 用 Telnet/nc 手动发送 HTTP:

    $ echo -e 'GET / HTTP/1.1\\r\\nHost: httpbin.org\\r\\nConnection: close\\r\\n\\r\\n' | nc httpbin.org 80
    HTTP/1.1 503 Service Temporarily Unavailable
    Server: awselb/2.0
    Date: Tue, 16 Jun 2026 11:57:59 GMT
    Content-Type: text/html
    Content-Length: 162
    Connection: close

    7.5 TFTP 协议

    TFTP (Trivial File Transfer Protocol, RFC 1350) 是简化的文件传输协议:

    特性FTPTFTP
    传输层 TCP UDP
    端口 21/20 69
    认证
    目录浏览
    用途 通用文件传输 PXE 启动/固件升级

    7.6 SMTP 和 POP3 协议

    SMTP (Simple Mail Transfer Protocol, RFC 5321): 发送邮件,端口 25/tcp

    POP3 (Post Office Protocol v3, RFC 1939): 接收邮件,端口 110/tcp

    SMTP 命令流程:

    客户端 SMTP 服务器
    │─── EHLO hostname ──────────→ │ 问候
    │─── MAIL FROM:<sender> ─────→ │ 指定发件人
    │─── RCPT TO:<receiver> ─────→ │ 指定收件人
    │─── DATA ──────────────────→ │ 开始邮件内容
    │─── Subject: Test\\r\\n\\r\\n │
    │─── Hello\\r\\n. ────────────→ │ 以 . 结束
    │─── QUIT ──────────────────→ │ 退出

    7.7 应用层协议端口汇总

    协议端口传输层用途
    DNS 53 UDP/TCP 域名解析
    FTP 21/20 TCP 文件传输
    HTTP 80 TCP Web 服务
    HTTPS 443 TCP 安全 Web
    Telnet 23 TCP 远程终端
    TFTP 69 UDP 简单文件传输
    SMTP 25 TCP 发送邮件
    POP3 110 TCP 接收邮件
    IMAP 143 TCP 邮件访问
    SSH 22 TCP 安全远程登录

    协议栈全景总结

    ┌─────────────────────────────────────────────────────────────┐
    │ 应用层 (Application) │
    │ DNS:53 FTP:21/20 HTTP:80 Telnet:23 SMTP:25 POP3:110 │
    ├────────────────────────┬────────────────────────────────────┤
    │ TCP (可靠传输) │ UDP (快速传输) │
    │ 三次握手/四次挥手 │ 无连接/8字节头部 │
    │ 滑动窗口/拥塞控制 │ DNS/视频/游戏 │
    ├────────────────────────┴────────────────────────────────────┤
    │ 网络层 (Internet) │
    │ IP (寻址/路由) ARP (IP→MAC) ICMP (错误/诊断) │
    │ IGMP (组播) RARP (MAC→IP) │
    ├─────────────────────────────────────────────────────────────┤
    │ 链路层 (Link) │
    │ 以太网 (802.3) PPP SLIP MTU:1500 │
    │ MAC: fa:16:3e:xx:xx:xx │
    ├─────────────────────────────────────────────────────────────┤
    │ 物理层 (Physical) │
    │ 双绞线 光纤 无线电波 │
    └─────────────────────────────────────────────────────────────┘


    踩坑记录

    问题原因解决方案
    tcpdump 显示 bad udp cksum 云虚拟机网卡 TX Checksum Offloading,tcpdump 在协议栈抓包看到未计算校验和 正常现象,实际发送时网卡硬件计算正确校验和
    ip maddr add 224.1.1.1 报 Invalid address length ip maddr 只接受链路层组播地址 (6字节) 通过应用 socket IP_ADD_MEMBERSHIP 加入 IP 组播组
    traceroute 多跳 * * * 路由器禁止 ICMP 响应或防火墙过滤 使用 traceroute -T (TCP) 或 traceroute -I (ICMP)
    httpbin.org 返回 503 服务端临时过载 换用其他测试服务器或自行部署
    ping -R 仅记录 9 跳 IP Record Route 选项最多 9 个地址 (39字节选项空间) 使用 traceroute 追踪更多跳数

    文档版本: v1.0 | 实验日期: 2026-06-16 | 集群: ecs-76fc (华为云)

    赞(0)
    未经允许不得转载:171主机测评 » TCP/IP 协议栈实战 — 7 个实验详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址