第1章 网络模型与数据流转
学习目标
- 理解OSI七层与TCP/IP四层模型的关系
- 掌握数据封装与解封装过程
- 了解关键网络指标(MTU、MSS)
- 能够使用工具观察网络数据流转
🔬 原理
OSI七层与TCP/IP四层模型
OSI七层模型:
应用层 (Application) - HTTP、DNS、SSH
表示层 (Presentation) - 加密、压缩
会话层 (Session) - 会话管理
传输层 (Transport) - TCP、UDP
网络层 (Network) - IP、ICMP
数据链路层 (Data Link) - 以太网、ARP
物理层 (Physical) - 电信号、光信号
TCP/IP四层模型:
应用层 - 用户数据
传输层 - 端到端通信
网络层 - 路由寻址
链路层 - 物理传输
对应关系:
- 应用层(HTTP/DNS/SSH)→ 用户数据
- 传输层(TCP/UDP)→ 端到端通信
- 网络层(IP/ICMP)→ 路由寻址
- 链路层(以太网/ARP)→ 物理传输
数据封装过程
应用数据 → TCP段 → IP包 → 以太网帧 → 物理信号
详细过程:
- 应用层:用户数据(如HTTP请求)
- 传输层:添加TCP头(源端口、目标端口、序列号等)
- 网络层:添加IP头(源IP、目标IP、TTL等)
- 链路层:添加以太网头(源MAC、目标MAC、类型)
- 物理层:转换为电信号传输
关键指标
MTU(Maximum Transmission Unit):
- 链路层最大帧大小
- 以太网默认:1500字节
- 影响:超过MTU需要分片
MSS(Maximum Segment Size):
- TCP层最大段大小
- 计算公式:MSS = MTU - IP头(20) - TCP头(20) = 1460
- 影响:TCP传输效率
️ 实现
Linux网络栈层次
// 内核网络栈关键结构
struct sk_buff {
struct net_device *dev; // 网络设备
unsigned char *head; // 数据缓冲区起始
unsigned char *data; // 当前数据指针
unsigned int len; // 数据长度
__u16 protocol; // 协议类型
// ... 更多字段
};
数据流转路径
网卡 → DMA → Ring Buffer → 硬中断 → 软中断(NAPI)
→ GRO → 协议栈 → Socket缓冲区 → 应用
🛠️ 命令
基础网络命令
# 查看网络接口
ip link show
# 查看IP地址
ip addr show
# 查看路由表
ip route show
# 测试连通性
ping -c 3 1.1.1.1
# 路由追踪
traceroute 8.8.8.8
网络统计信息
# 查看网络统计
cat /proc/net/dev
# 查看协议统计
cat /proc/net/snmp
# 查看连接统计
ss -s
代码
简单网络客户端
// simple_client.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket");
return 1;
}
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(80),
.sin_addr.s_addr = inet_addr("8.8.8.8")
};
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("connect");
close(sock);
return 1;
}
printf("Connected to 8.8.8.8:80\n");
close(sock);
return 0;
}
编译运行:
gcc simple_client.c -o simple_client
./simple_client
🧪 实验
实验1:观察数据封装
目标:通过抓包观察ICMP数据封装过程
步骤:
# 1. 启动抓包(一个终端)
sudo tcpdump -i any -nn icmp
# 2. 发送ping(另一个终端)
ping -c 3 8.8.8.8
# 3. 观察输出
# 应该看到类似:
# IP 192.168.1.10 > 8.8.8.8: ICMP echo request
# IP 8.8.8.8 > 192.168.1.10: ICMP echo reply
预期结果:
- 看到ICMP Echo Request和Reply
- 观察到IP层封装(源IP、目标IP)
- 理解ping的工作原理
实验2:MTU与分片测试
目标:理解MTU对数据传输的影响
步骤:
# 1. 查看当前MTU
ip link show eth0
# 2. 测试不同大小的包
ping -M do -s 1472 8.8.8.8 # 成功(1500-28=1472)
ping -M do -s 1473 8.8.8.8 # 失败(超过MTU)
# 3. 修改MTU观察影响
sudo ip link set dev eth0 mtu 1400
ping -M do -s 1372 8.8.8.8 # 新的最大包大小
预期结果:
- 理解MTU限制
- 观察分片行为
- 学会MTU调优
实验3:协议栈层次观察
目标:使用tcpdump观察不同协议层
步骤:
# 1. 抓取HTTP流量
sudo tcpdump -i any -nn 'port 80' -A
# 2. 发送HTTP请求
curl -v http://httpbin.org/get
# 3. 观察各层信息
# 以太网层:源MAC、目标MAC
# IP层:源IP、目标IP、TTL
# TCP层:源端口、目标端口、序列号
# HTTP层:请求方法、URL、头部
预期结果:
- 理解分层封装
- 学会协议分析
- 掌握抓包技巧
排错
常见问题排查
问题1:无法ping通外网
# 检查链路
ip link show
# 检查IP配置
ip addr show
# 检查路由
ip route show
# 检查DNS
nslookup 8.8.8.8
问题2:MTU问题导致连接异常
# 检查MTU
ip link show | grep mtu
# 测试路径MTU
tracepath 8.8.8.8
# 调整MTU
sudo ip link set dev eth0 mtu 1400
问题3:网络延迟高
# 测试延迟
ping -c 10 8.8.8.8
# 路由追踪
traceroute 8.8.8.8
# 检查网络统计
cat /proc/net/snmp | grep -i tcp
排错清单
- [ ] 检查物理连接(网线、网卡状态)
- [ ] 验证IP配置(IP地址、子网掩码、网关)
- [ ] 确认路由表(默认路由、静态路由)
- [ ] 测试DNS解析(nslookup、dig)
- [ ] 检查防火墙规则(iptables、ufw)
- [ ] 验证MTU设置(避免分片问题)
- [ ] 查看系统日志(dmesg、/var/log/syslog)