TCP/IP 协议栈
一、OSI 七层 vs TCP/IP 四层
OSI 七层 TCP/IP 四层 协议
─────────────────────────────────────────────────
应用层 ─┐
表示层 ├─ 应用层 HTTP/SSH/DNS/MQTT
会话层 ─┘
传输层 传输层 TCP/UDP
网络层 网络层 IP/ICMP/ARP
数据链路层 ─┐
物理层 ├─ 网络接口层 Ethernet/Wi-Fi
─┘
二、Linux 网络栈结构
应用 socket
↓
BSD Socket 层
↓
INET Socket(TCP/UDP)
↓
TCP / UDP
↓
IP
↓
邻居子系统(ARP / ND)
↓
Netdev 子系统
↓
网络设备驱动
↓
网卡硬件
三、关键协议
1. ARP(地址解析)
- IP → MAC
- 内核维护 ARP 表
arp -a查看
2. IP(Internet Protocol)
- 无连接、不可靠
- IPv4:32 位地址
- IPv6:128 位地址
3. ICMP(Internet Control Message Protocol)
- 错误报告
ping用 ICMP Echotraceroute用 ICMP TTLDestination Unreachable、Time Exceeded
4. UDP(User Datagram Protocol)
- 无连接、不可靠
- 简单:包头 8 字节
- 适用:DNS、视频流、游戏、SNMP
5. TCP(Transmission Control Protocol)
- 面向连接、可靠
- 三次握手
- 流量控制、拥塞控制
- 包头 20-60 字节
四、TCP 三次握手 / 四次挥手
三次握手
Client Server
| --- SYN(seq=x) --> |
| <-- SYN+ACK(seq=y, ack=x+1) |
| --- ACK(ack=y+1) -> |
| |
连接建立
四次挥手
Client Server
| --- FIN --> |
| <-- ACK --- |
| <-- FIN --- |
| --- ACK --> |
| |
连接关闭
五、TCP 状态机
LISTEN → SYN_RCVD → ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
↑ ↓
SYN_SENT CLOSE_WAIT
TIME_WAIT 持续 2 × MSL(60s~240s),防止最后 ACK 丢失。
六、TCP 关键参数
/proc/sys/net/ipv4/tcp_*
tcp_keepalive_time 默认 7200s
tcp_keepalive_intvl 默认 75s
tcp_keepalive_probes 默认 9 次
tcp_max_syn_backlog SYN 队列长度
tcp_fin_timeout FIN 超时
tcp_tw_reuse TIME_WAIT 复用(客户端)
tcp_tw_recycle 已废弃
tcp_max_tw_buckets TIME_WAIT 数量上限
tcp_slow_start_after_idle 空闲后慢启动
tcp_window_scaling 窗口缩放
tcp_timestamps 时间戳
七、内核网络配置
# 查看 TCP 状态
netstat -ant | awk '{print $6}' | sort | uniq -c
ss -s
# IP 配置
ip addr add 192.168.1.100/24 dev eth0
ip link set eth0 up
ip route add default via 192.168.1.1
# DNS
echo "nameserver 8.8.8.8" > /etc/resolv.conf
# 接口信息
ethtool eth0
mii-tool eth0
八、内核结构
// 主要结构
struct sock {
// ...
struct sk_buff_head sk_receive_queue;
struct sk_buff_head sk_write_queue;
// ...
};
struct inet_sock {
struct sock sk;
__be32 inet_saddr; // 源 IP
__be32 inet_daddr; // 目的 IP
__be16 inet_sport; // 源端口
__be16 inet_dport; // 目的端口
// ...
};
struct tcp_sock {
struct inet_sock inet;
// 滑动窗口、拥塞控制、序列号等
u32 snd_una; // 未确认
u32 snd_nxt; // 下一个发送
u32 rcv_nxt; // 下一个期望
// ...
};
九、TCP 连接数
理论上限:
- 客户端:受 fd 限制
- 服务端:受 fd、内存、端口限制(65535)
实际:
- 服务端 ~10k 连接(默认配置)
- 调优后 ~100k(需要大内存)
十、嵌入式 TCP/IP 栈
- lwIP:最常用,资源占用极小,可独立运行
- uIP:lwIP 的前身
- NicheStack / InterNiche:商业
- CycloneTCP:开源、可商用
适用场景:
- 没有 MMU 的 MCU
- 不跑 Linux 的小芯片
- 资源极有限
十一、调试
tcpdump -i eth0 -nn
tcpdump -i eth0 port 80
tcpdump -i eth0 host 192.168.1.100 and tcp
tshark -i eth0 -Y 'tcp.port == 80'
ss -ant
ss -tinp
十二、内核 netstat
# /proc/net/tcp
# /proc/net/udp
# /proc/net/unix (Unix domain)
# /proc/net/arp
# /proc/net/route