理解网络编程的起点是理解协议栈的分层思想。每一层隐藏了底层的实现细节,通过标准化的接口为上层提供服务。
一、OSI 七层模型 vs TCP/IP 四层模型 1.1 分层对照 ┌──────────────┬──────────────────────────────────┬──────────────────┐
│ OSI │ 功能 │ TCP/IP │
├──────────────┼──────────────────────────────────┼──────────────────┤
│ 7 应用层 │ HTTP、FTP、SSH、gRPC、WebSocket │ │
│ 6 表示层 │ 数据格式、加密解密、压缩 │ 应用层 │
│ 5 会话层 │ 会话建立、管理、终止 │ │
├──────────────┼──────────────────────────────────┼──────────────────┤
│ 4 传输层 │ TCP、UDP、端口号 │ 传输层 │
├──────────────┼──────────────────────────────────┼──────────────────┤
│ 3 网络层 │ IP、ICMP、路由选择、子网划分 │ 互联网层 │
├──────────────┼──────────────────────────────────┼──────────────────┤
│ 2 数据链路层 │ MAC 地址、以太网、ARP、交换机 │ 网络接口层 │
│ 1 物理层 │ 网线、光纤、无线、比特流传输 │ │
└──────────────┴──────────────────────────────────┴──────────────────┘
1.2 分层数据交换逻辑 发送方 接收方
│ ▲
│ Application Data │ Application Data
▼ │
┌──────┐ ┌──────┐
│ HTTP │ ← 应用层:HTTP 请求报文 │ HTTP │
├──────┤ ├──────┤
│ TCP │ ← 传输层:Segment(段) │ TCP │
├──────┤ ├──────┤
│ IP │ ← 网络层:Packet(包) │ IP │
├──────┤ ├──────┤
│ ETH │ ← 链路层:Frame(帧) │ ETH │
└──────┘ └──────┘
│ ▲
▼ 物理层传输 │
二、数据封装与解封装 2.1 封装过程 应用层数据(Payload)
│
▼ + TCP Header(20-60 bytes)
传输层段(Segment)
│
▼ + IP Header(20 bytes)
网络层包(Packet)
│
▼ + ETH Header(14 bytes) + ETH Trailer(4 bytes)
链路层帧(Frame)
│
▼ 转化为比特流发送
物理层
2.2 各层 PDU(Protocol Data Unit) 层次 名称 标识 说明 应用层 Data / Message 无 HTTP 请求/响应体 传输层 Segment Port TCP 段/UDP 数据报 网络层 Packet IP 地址 IP 数据报 链路层 Frame MAC 地址 以太网帧 物理层 Bit 电信号/光信号 比特流
2.3 Wireshark 实际观察 Frame 42: 1514 bytes on wire ← 链路层帧
Ethernet II, Src: aa:bb:cc:dd:ee:ff ← 以太网头部
Internet Protocol Version 4 ← IP 头部
Transmission Control Protocol ← TCP 头部
Hypertext Transfer Protocol ← HTTP 数据
三、IP 协议核心 3.1 IPv4 报文头部 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3.2 子网划分 // Java 中计算子网
public class SubnetUtils {
public static void main ( String [] args ) {
// CIDR 表示法:192.168.1.0/24
// 网络地址:192.168.1.0
// 子网掩码:255.255.255.0(前 24 位为 1)
// 可用主机数:2^(32-24) - 2 = 254
int prefix = 24 ;
int hostBits = 32 - prefix ;
int hostCount = ( 1 << hostBits ) - 2 ; // 减去网络地址和广播地址
System . out . println ( "可用主机数: " + hostCount ); // 254
// 判断 IP 是否在同一子网
String ip1 = "192.168.1.100" ;
String ip2 = "192.168.1.200" ;
String mask = "255.255.255.0" ;
int network1 = ipToInt ( ip1 ) & ipToInt ( mask );
int network2 = ipToInt ( ip2 ) & ipToInt ( mask );
System . out . println ( "同子网: " + ( network1 == network2 ));
}
static int ipToInt ( String ip ) {
String [] parts = ip . split ( "\\." );
return ( Integer . parseInt ( parts [ 0 ] ) << 24 )
| ( Integer . parseInt ( parts [ 1 ] ) << 16 )
| ( Integer . parseInt ( parts [ 2 ] ) << 8 )
| Integer . parseInt ( parts [ 3 ] );
}
}
3.3 IPv6 特点 特性 IPv4 IPv6 地址长度 32 位 128 位 地址数量 约 43 亿 3.4 × 10^38 头部长度 可变(20-60 bytes) 固定(40 bytes) 安全性 IPsec 可选 IPsec 内置 表示格式 点分十进制 冒号分隔十六进制
示例 IPv6 地址:
完整:2001:0db8:85a3:0000:0000:8a2e:0370:7334
压缩:2001:db8:85a3::8a2e:370:7334
四、ARP 协议 4.1 地址解析过程 主机 A(192.168.1.10)需要发送数据给主机 B(192.168.1.20)
1. A 检查 ARP 缓存,无 B 的 MAC 地址
2. A 发送 ARP 请求(广播):
"谁的 IP 是 192.168.1.20?告诉 192.168.1.10(MAC: aa:bb:cc:dd:ee:ff)"
3. 所有主机收到请求,只有 B 响应(单播):
"我是 192.168.1.20,MAC 是 11:22:33:44:55:66"
4. A 将 B 的 IP-MAC 映射存入 ARP 缓存
5. A 发送数据帧给 B
4.2 Java ARP 操作 // 通过 InetAddress 获取 MAC 地址(平台依赖)
InetAddress addr = InetAddress . getByName ( "192.168.1.1" );
NetworkInterface ni = NetworkInterface . getByInetAddress ( addr );
byte [] mac = ni . getHardwareAddress ();
// 使用 ProcessBuilder 执行 arp 命令(Linux/macOS)
Process process = new ProcessBuilder ( "arp" , "-a" ). start ();
BufferedReader reader = new BufferedReader ( new InputStreamReader ( process . getInputStream ()));
String line ;
while (( line = reader . readLine ()) != null ) {
System . out . println ( line );
}
五、ICMP 与 Ping // Java 中使用 ProcessBuilder 执行 ping
public class PingTest {
public static boolean ping ( String host , int timeoutMs ) throws Exception {
ProcessBuilder pb = new ProcessBuilder ( "ping" , "-c" , "1" , "-W" , String . valueOf ( timeoutMs / 1000 ), host );
Process process = pb . start ();
boolean finished = process . waitFor ( timeoutMs + 1000 , TimeUnit . MILLISECONDS );
if ( ! finished ) {
process . destroyForcibly ();
return false ;
}
return process . exitValue () == 0 ;
}
// 使用 isReachable(基于 ICMP 或 TCP echo)
public static boolean isReachable ( String host , int timeoutMs ) throws Exception {
return InetAddress . getByName ( host ). isReachable ( timeoutMs );
}
public static void main ( String [] args ) throws Exception {
System . out . println ( ping ( "baidu.com" , 3000 ));
System . out . println ( isReachable ( "baidu.com" , 3000 ));
}
}
六、MTU 与分片 6.1 MTU(Maximum Transmission Unit) 接口类型 默认 MTU 以太网 1500 bytes PPPoE 1492 bytes IEEE 802.11 2304 bytes 回环接口 65536 bytes Jumbo Frame 9000 bytes
6.2 路径 MTU 发现 发送方 接收方
│ ─── 发送 DF=1(Don't Fragment)的包 ───→ │
│ │
│ ←── 收到 ICMP "Fragmentation Needed" ───│ MTU 只有 1400
│ │
│ ─── 发送 1400 bytes 的包 ─────────────→ │
│ │
// Java Socket 设置 MTU
Socket socket = new Socket ();
socket . setReceiveBufferSize ( 65536 );
socket . setSendBufferSize ( 65536 );
// NIO SocketChannel
SocketChannel channel = SocketChannel . open ();
channel . socket (). setReceiveBufferSize ( 65536 );
七、常用网络工具 工具 用途 示例 ping 测试连通性 ping -c 4 baidu.comtraceroute 路由追踪 traceroute baidu.comnetstat 查看连接 netstat -tlnpss 替代 netstat ss -tlnptcpdump 抓包 tcpdump -i eth0 port 80Wireshark 图形化分析 分析 pcap 文件 telnet 测试端口 telnet baidu.com 80nc 网络瑞士军刀 nc -zv baidu.com 80curl HTTP 请求 curl -v https://api.example.comnmap 端口扫描 nmap -sS 192.168.1.1
八、总结 层次 核心协议 关键概念 应用层 HTTP/HTTPS、gRPC、DNS 请求/响应、RPC 传输层 TCP、UDP 端口、连接、可靠性 网络层 IP、ICMP、ARP 地址、路由、分片 链路层 Ethernet、Wi-Fi MAC、帧、交换机
协议栈的分层设计体现了软件工程中"关注点分离"的核心思想。每一层专注于自己的职责,通过标准化的接口与上下层交互,使得整个网络通信系统既灵活又可靠。
继续阅读
探索更多技术文章 浏览归档,发现更多关于系统设计、工具链和工程实践的内容。