引言
上一篇我们学习了OSI七层模型,理解了网络分层的设计哲学。但实际工作中,我们更常听到的是:
- “这是个TCP/IP的问题”
- “HTTP运行在TCP之上”
- “IP地址是网络层的”
很少有人说"这是会话层的问题"或"表示层出错了"。
为什么?因为互联网实际使用的是TCP/IP四层模型,而不是OSI七层模型。
TCP/IP模型的诞生
历史背景
1969年:ARPANET诞生(互联网的前身) 1974年:TCP/IP协议诞生 1981年:TCP/IP正式分离为TCP和IP 1983年:ARPANET全面采用TCP/IP 1984年:OSI模型发布
时间线:TCP/IP先于OSI模型存在!
为什么TCP/IP胜出?
实践先行
- TCP/IP先在ARPANET上实现
- 经过实际验证,稳定可靠
- 已经有大量应用基于TCP/IP
简洁实用
- 4层比7层简单
- 避免过度设计
- 工程实践优于理论完美
开放免费
- TCP/IP协议是开放的
- 任何人都可以实现
- OSI标准复杂且需要付费
TCP/IP四层模型
┌─────────────────────────────────┐
│ 应用层 (Application Layer) │ HTTP, FTP, DNS, SMTP
├─────────────────────────────────┤
│ 传输层 (Transport Layer) │ TCP, UDP
├─────────────────────────────────┤
│ 网络层 (Internet Layer) │ IP, ICMP, ARP
├─────────────────────────────────┤
│ 链路层 (Link Layer) │ Ethernet, WiFi
└─────────────────────────────────┘
与OSI模型的对应关系
OSI七层 TCP/IP四层
────────────────────────────
应用层 ]
表示层 ] ───→ 应用层
会话层 ]
────────────────────────────
传输层 ───→ 传输层
────────────────────────────
网络层 ───→ 网络层
────────────────────────────
数据链路层]
物理层 ] ───→ 链路层
────────────────────────────
每层详解
1. 链路层(Link Layer)
职责:在直连设备之间传输数据帧
关键协议:
- 以太网(Ethernet):局域网最常用
- WiFi(802.11):无线局域网
- PPP:点对点协议
关键概念:
- MAC地址:物理地址,48位
- 帧(Frame):数据单元
- 交换机:根据MAC地址转发
2. 网络层(Internet Layer)
职责:跨网络传输数据包,负责寻址和路由
关键协议:
- IP(Internet Protocol):互联网协议
- IPv4:32位地址
- IPv6:128位地址
- ICMP:控制消息协议(ping使用)
- ARP:地址解析协议(IP → MAC)
关键概念:
- IP地址:逻辑地址
- 路由:数据包转发路径
- 分片:大包拆小包
3. 传输层(Transport Layer)
职责:端到端的数据传输
关键协议:
- TCP(Transmission Control Protocol)
- 面向连接
- 可靠传输
- 流量控制、拥塞控制
- UDP(User Datagram Protocol)
- 无连接
- 不可靠传输
- 低延迟
关键概念:
- 端口号(Port):区分不同应用
- 三次握手:TCP连接建立
- 四次挥手:TCP连接关闭
4. 应用层(Application Layer)
职责:为应用程序提供网络服务
关键协议:
- HTTP/HTTPS:Web浏览
- DNS:域名解析
- FTP:文件传输
- SMTP/POP3/IMAP:邮件
- SSH:远程登录
- WebSocket:双向通信
- gRPC:RPC框架
数据传输的完整流程
发送方(封装过程)
应用层:生成HTTP请求
↓
[GET /index.html HTTP/1.1]
↓
传输层:添加TCP头部
↓
[TCP头 | HTTP请求]
↓
网络层:添加IP头部
↓
[IP头 | TCP头 | HTTP请求]
↓
链路层:添加以太网头和尾
↓
[以太网头 | IP头 | TCP头 | HTTP请求 | 以太网尾]
↓
发送到网络
接收方(解封装过程)
从网络接收数据
↓
链路层:检查MAC地址,去掉以太网头尾
↓
网络层:检查IP地址,去掉IP头
↓
传输层:检查端口号,去掉TCP头
↓
应用层:处理HTTP请求
实战案例:查看网络连接
案例1:使用netstat查看TCP/IP连接
在你的电脑上打开终端,执行以下命令:
# macOS/Linux
netstat -an | grep ESTABLISHED
# 或使用ss命令(更现代)
ss -tan state established
输出示例:
tcp4 0 0 192.168.1.100.52341 140.82.121.4.443 ESTABLISHED
tcp4 0 0 192.168.1.100.52340 52.84.73.122.443 ESTABLISHED
解读:
192.168.1.100:本机IP地址(网络层)52341:本机端口号(传输层)140.82.121.4:目标IP地址(GitHub服务器)443:目标端口号(HTTPS)ESTABLISHED:TCP连接状态
TCP/IP层次对应:
- 应用层:HTTPS协议(浏览器访问GitHub)
- 传输层:TCP协议,端口52341 → 443
- 网络层:IP协议,192.168.1.100 → 140.82.121.4
- 链路层:以太网帧(通过MAC地址传输)
案例2:使用ping测试网络连通性
ping -c 4 www.google.com
输出示例:
PING www.google.com (142.251.42.228): 56 data bytes
64 bytes from 142.251.42.228: icmp_seq=0 ttl=115 time=30.123 ms
64 bytes from 142.251.42.228: icmp_seq=1 ttl=115 time=29.876 ms
64 bytes from 142.251.42.228: icmp_seq=2 ttl=115 time=30.456 ms
64 bytes from 142.251.42.228: icmp_seq=3 ttl=115 time=30.234 ms
--- www.google.com ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 29.876/30.172/30.456/0.218 ms
协议分析:
- 应用层:无(ping不是应用层协议)
- 传输层:无(ICMP直接运行在网络层)
- 网络层:ICMP协议(Internet Control Message Protocol)
- 链路层:以太网
关键信息:
icmp_seq:序列号ttl=115:生存时间(Time To Live),经过的路由器跳数time=30.123 ms:往返时延(Round-Trip Time)
案例3:使用traceroute追踪路由路径
# macOS/Linux
traceroute www.baidu.com
# Windows
tracert www.baidu.com
输出示例:
traceroute to www.baidu.com (180.101.50.242), 30 hops max, 60 byte packets
1 192.168.1.1 (192.168.1.1) 1.234 ms 1.123 ms 1.056 ms
2 10.255.255.1 (10.255.255.1) 3.456 ms 3.234 ms 3.567 ms
3 61.135.169.121 (61.135.169.121) 5.678 ms 5.456 ms 5.789 ms
4 61.135.38.194 (61.135.38.194) 7.890 ms 7.678 ms 7.901 ms
5 180.101.50.242 (180.101.50.242) 10.234 ms 10.123 ms 10.345 ms
路由路径解读:
- 第1跳:家用路由器(192.168.1.1)
- 第2跳:运营商网关(10.255.255.1)
- 第3-4跳:运营商骨干网
- 第5跳:目标服务器(百度)
TCP/IP层次应用:
- 网络层:IP协议负责路由选择
- 每一跳都是一个路由器,根据路由表转发数据包
- TTL递减:每经过一个路由器,TTL减1
案例4:TCP/IP在微服务中的应用
假设你有一个订单服务调用支付服务:
// 订单服务(Order Service)
String result = restTemplate.getForObject(
"http://payment-service:8080/api/pay", // 应用层:HTTP协议
String.class
);
TCP/IP层次拆解:
应用层(Application Layer):
- 协议:HTTP/1.1
- 请求方法:GET
- URL:
http://payment-service:8080/api/pay - 请求头:
Host: payment-service,User-Agent: ...
传输层(Transport Layer):
- 协议:TCP
- 源端口:随机端口(如52341)
- 目标端口:8080
- 三次握手建立连接
- 四次挥手关闭连接
网络层(Internet Layer):
- 协议:IP
- DNS解析:
payment-service→172.17.0.3(Docker内网IP) - 源IP:
172.17.0.2(订单服务) - 目标IP:
172.17.0.3(支付服务) - 路由:通过Docker bridge网络转发
链路层(Link Layer):
- 协议:以太网(在Docker bridge上)
- ARP解析:IP → MAC地址
- MAC寻址:数据帧在同一网段传输
案例5:不同场景的协议选择
| 场景 | 应用层协议 | 传输层协议 | 原因 |
|---|---|---|---|
| 网页浏览 | HTTP/HTTPS | TCP | 需要可靠传输,确保网页完整 |
| 文件下载 | HTTP/FTP | TCP | 需要可靠传输,不能丢失数据 |
| 视频直播 | RTMP/HLS | TCP | 需要顺序传输,低延迟 |
| 实时语音 | RTP | UDP | 容忍少量丢包,追求低延迟 |
| DNS查询 | DNS | UDP | 请求简单,不需要建立连接 |
| 数据库连接 | MySQL协议 | TCP | 需要可靠传输,保证事务完整性 |
| 消息队列 | AMQP/Kafka | TCP | 需要可靠传输,不能丢消息 |
| 游戏数据 | 自定义协议 | UDP | 追求低延迟,位置数据可容忍丢失 |
微服务架构中的TCP/IP实践
在微服务架构中,TCP/IP的每一层都有实际应用:
应用层(微服务通信协议选择):
HTTP/REST → 简单、通用、易调试(Spring Cloud)
gRPC → 高性能、跨语言(Google内部标准)
Dubbo → 国内流行、功能丰富(阿里开源)
WebSocket → 双向通信、实时推送
消息队列 → 异步解耦、削峰填谷
传输层(连接管理):
连接池 → 复用TCP连接,提升性能
Keep-Alive → 长连接,减少握手开销
超时配置 → connectTimeout, readTimeout
重试策略 → 失败重试,提高可用性
网络层(服务发现与路由):
服务注册 → Eureka, Consul, Nacos
负载均衡 → Ribbon, Nginx, LVS
API网关 → Spring Cloud Gateway, Kong
容器网络 → Docker bridge, Kubernetes CNI
链路层(物理网络):
机房网络 → 以太网交换机
跨机房通信 → 专线、VPN
容器网络 → veth pair, bridge
常见问题解答
Q1: 为什么TCP/IP是4层,而不是更多或更少?
答案:这是工程实践和理论平衡的结果。
- 3层太少:无法区分传输层和应用层,TCP和HTTP混在一起
- 5层太多:会话层和表示层在实践中很少独立使用
- 4层刚好:每层职责清晰,互不重叠
Q2: ARP协议到底属于哪一层?
答案:有争议,取决于分类标准。
- 从功能看:ARP解决IP到MAC的映射,属于网络层
- 从实现看:ARP直接工作在数据链路层之上,属于链路层
- 实际归类:通常归为网络层(本文采用此分类)
Q3: WebSocket运行在哪一层?
答案:应用层
虽然WebSocket使用HTTP握手升级,但它是一个独立的应用层协议:
- 建立在TCP之上(传输层)
- 使用HTTP升级机制(应用层)
- 提供全双工通信(应用层功能)
总结
核心要点
TCP/IP是实践标准
- OSI是理论模型
- TCP/IP是实际使用
四层模型更简洁
- 链路层:物理传输
- 网络层:IP寻址和路由
- 传输层:TCP/UDP端到端
- 应用层:HTTP等应用协议
每层有明确职责
- 分层解耦
- 独立演进
- 互操作性
下一篇预告
下一篇我们将通过一个实际案例,跟踪一个数据包的完整旅程,从应用发送到网络接收,看看数据包经历了什么。
思考题:
- 为什么TCP/IP模型是4层,而不是3层或5层?
- ARP协议为什么放在网络层,而不是链路层?
- WebSocket运行在哪一层?