数据封包拆包与协议
一、Socket 发送函数详解
send() 函数
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数解析:
-
sockfd:socket 函数返回的文件描述符(旧fd) -
buf:要发送的消息缓冲区 -
len:要发送的消息长度(字节数) -
flags:发送方式标志-
0:正常发送(阻塞) -
MSG_DONTWAIT:非阻塞发送 -
MSG_OOB:发送带外数据(紧急数据)
-
返回值:
-
成功:实际发送的字节数
-
失败:-1
示例:
char msg[] = "Hello Server";
int ret = send(sockfd, msg, strlen(msg), 0);
if (ret == -1) {
perror("send failed");
}
connect() 函数
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能: 客户端主动连接服务器,发起 TCP 三次握手
参数解析:
-
sockfd:本地 socket 创建的套接字 ID -
addr:目标服务器的地址信息 -
addrlen:地址结构体的长度
返回值:
-
成功:0
-
失败:-1
示例:
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = inet_addr("192.168.1.100");
if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
perror("connect failed");
}

二、网络协议分层与数据封装
数据包封装过程
应用层数据 → TCP/UDP头部 → IP头部 → MAC头部 → 物理信号
1. MAC 头部(数据链路层)
-
作用:局域网内设备间的寻址
-
包含:源MAC地址、目标MAC地址
-
大小:14字节
2. IP 头部(网络层)
struct ip_header {
uint8_t version:4; // IP版本(IPv4=4)
uint8_t ihl:4; // 头部长度
uint8_t tos; // 服务类型
uint16_t total_len; // 总长度
uint16_t id; // 标识符
uint16_t frag_off; // 分片偏移
uint8_t ttl; // 生存时间
uint8_t protocol; // 上层协议(TCP=6, UDP=17)
uint16_t checksum; // 校验和
uint32_t src_addr; // 源IP地址
uint32_t dst_addr; // 目标IP地址
};
关键字段解释:
-
ttl(生存周期):默认64,数据每经过一个路由器减1,为0时丢弃 -
ip_flag:-
D:是否允许分片(0=允许,1=不允许)
-
M:是不是最后一片(0=最后,1=还有)
-
3. TCP 头部(传输层)
struct tcp_header {
uint16_t src_port; // 源端口
uint16_t dst_port; // 目标端口
uint32_t seq_num; // 序列号
uint32_t ack_num; // 确认号
uint8_t data_offset:4; // 数据偏移
uint8_t reserved:4; // 保留位
uint8_t flags; // 标志位
uint16_t window; // 窗口大小
uint16_t checksum; // 校验和
uint16_t urgent_ptr; // 紧急指针
};
TCP 标志位:
URG ACK PSH RST SYN FIN
↑ ↑ ↑ ↑ ↑ ↑
紧急 确认 推送 重置 同步 结束
详细解释:
-
A(ACK):确认位,表示确认号有效 -
P(PSH):推送位,要求立即传递数据给应用层 -
R(RST):重置位,强制断开连接 -
S(SYN):同步位,建立连接请求 -
F(FIN):结束位,断开连接请求
4. UDP 头部
struct udp_header {
uint16_t src_port; // 源端口
uint16_t dst_port; // 目标端口
uint16_t length; // UDP数据包长度
uint16_t checksum; // 校验和
};

TCP vs UDP:
| 特性 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接 | 无连接 |
| 可靠性 | 可靠,有重传 | 不可靠,可能丢包 |
| 速度 | 较慢 | 较快 |
| 头部大小 | 20字节 | 8字节 |
| 应用场景 | 文件传输、网页浏览 | 视频流、DNS查询 |
三、Wireshark 网络抓包工具
使用步骤:
# 1. 启动Wireshark(需要管理员权限)
sudo wireshark
# 2. 选择网络接口
# - 本机通信:loopback
# - 外网通信:ens33(以太网)
# - 不确定时:any(捕获所有接口)
常用过滤条件:
wireshark
# 按IP地址过滤
ip.addr == 192.168.1.100 # 显示该IP的所有数据包
ip.src == 192.168.1.100 # 显示该源IP的数据包
ip.dst == 192.168.1.100 # 显示该目标IP的数据包
# 按端口过滤
tcp.port == 80 # TCP端口80(HTTP)
udp.port == 53 # UDP端口53(DNS)
tcp.port == 443 # TCP端口443(HTTPS)
# 按协议过滤
http # 只显示HTTP协议
dns # 只显示DNS协议
tcp # 只显示TCP协议
# 组合过滤
ip.addr == 192.168.1.100 and tcp.port == 80
分析TCP三次握手:
1. [SYN] 客户端 → 服务器:我想连接
2. [SYN+ACK] 服务器 → 客户端:我准备好了,你呢?
3. [ACK] 客户端 → 服务器:我也准备好了,开始通信
四、HTTP 协议详解
HTTP 简介
-
用途:网页浏览数据传输
-
性质:应用层协议,基于 TCP
-
特点:无状态、请求-响应模式
WWW(万维网)
-
全称:World Wide Web
-
作用:互联网上的信息资源集合
URL(统一资源定位符)
格式:
http://主机名:端口号/路径?查询参数#片段标识
示例:
http://news.sohu.com:80/news/index.html?id=123#section1
默认端口:
-
HTTP:80(可省略)
-
HTTPS:443(可省略)
示例:
http://www.example.com/ # 使用默认端口80
https://www.example.com/ # 使用默认端口443
http://www.example.com:8080/ # 指定端口8080
五、HTTP 通信步骤

1.HTTP 请求报文格式
请求行
请求头部
空行
请求正文
2. 请求示例
GET /index.html HTTP/1.1 ← 请求行
Host: www.example.com ← 请求头开始
User-Agent: Mozilla/5.0
Accept: text/html
Accept-Language: zh-CN
Accept-Encoding: gzip
Connection: keep-alive
← 空行(头部结束)
(请求正文,GET通常没有)

3、HTTP请求头字段详解 
请求行
GET /index.html?name=value HTTP/1.1
↑ ↑ ↑
方法 资源路径+查询参数 协议版本
-
方法:GET(获取)、POST(提交)、PUT(更新)、DELETE(删除)
-
查询参数 :
?key1=value1&key2=value2
2. Host字段
Host: news.sohu.com
-
作用:指定虚拟主机(一个IP多个网站)
-
必需:HTTP/1.1要求必须包含
3. User-Agent字段
User-Agent: Mozilla/5.0 (Windows NT 10.0) Chrome/142.0.0.0
-
作用:告诉服务器客户端信息
-
包含:操作系统、浏览器、版本等
4. Accept系列字段
Accept: text/html,application/xml;q=0.9 ← 内容类型
Accept-Encoding: gzip, deflate ← 压缩方式
Accept-Language: zh-CN,zh;q=0.9 ← 语言偏好
- q参数:权重值,0-1,越大优先级越高
5. Connection字段
Connection: keep-alive
-
作用:控制TCP连接是否保持
-
keep-alive:长连接(可发送多个请求)
-
close:短连接(一个请求后就断开)
六、学习总结
核心知识点:
-
数据封装:应用层 → 传输层 → 网络层 → 链路层
-
TCP特性:连接、可靠、有序、流式
-
协议头部:理解各层协议字段含义
-
抓包分析:使用Wireshark调试网络程序
-
HTTP协议:无状态、请求-响应、基于TCP
实践建议:
-
使用Wireshark抓包分析自己的程序
-
实现简单的HTTP客户端
-
编写处理TCP粘包的解包函数
-
分析不同应用的网络协议特点


