TCP与IP协议
一、常见协议头分析
1.1 TCP首部
| 字段 | 作用 |
|---|---|
| 源端口 | 发送端应用程序的端口号,用于接收方回传数据时定位发送方进程 |
| 目的端口 | 接收端应用程序的端口号,用于定位数据要交给哪个进程 |
| 序号 | 标识发送数据的字节流编号,用于数据重组、确认和重传 |
| 确认号 | 期望收到的下一个字节序号,表示之前的数据已成功接收 |
| 源IP地址 | 发送端的IP地址,在网络层标识数据包来源 |
| 数据偏移 | 表示TCP首部的长度(以4字节为单位),用于定位数据部分的起始位置 |
| 保留 | 预留字段,供未来使用,目前必须置为0 |
| URG | 紧急指针标志位,为1时表示紧急指针有效 |
| ACK | 确认标志位,为1时确认号字段有效(连接建立后必须为1) |
| PSH | 推送标志位,为1时要求接收方尽快将数据交给应用层 |
| RST | 复位标志位,为1时表示连接出现异常,强制断开 |
| SYN | 同步标志位,为1时表示请求建立连接(三次握手中的同步序号) |
| FIN | 结束标志位,为1时表示发送方数据已发送完毕,请求断开连接 |
| 校验和 | 对整个TCP报文段(首部+数据)进行校验,检测传输错误 |
| 紧急指针 | 指向紧急数据的末尾位置(与序号字段配合使用),仅在URG=1时有效 |
| 选项 | 可选字段,如最大报文段长度(MSS)、窗口扩大因子、时间戳等 |
| 填充 | 用于保证TCP首部是4字节的整数倍(数据偏移字段的单位) |
| TCP数据部分 | 上层应用协议(如HTTP、FTP)的实际数据内容 |
1.2 IP首部
| 字段 | 长度 | 功能 |
|---|---|---|
| 版本号 | 4bit | 标识 IP 版本(IPv4=4,IPv6=6) |
| 首部长度 | 4bit | IP 头部的长度(单位:4字节,最小5=20字节,最大15=60字节) |
| 服务类型(TOS) | 8bit | 定义优先级、延迟、吞吐量;现用于区分服务(DSCP) 标记流量类别(如视频、语音优先级) |
| 总长度 | 16bit | 整个 IP 数据包总长度(头部+数据),最大 65535 字节 超过MTU时需要分片 |
| 标识 | 16bit | 唯一标识一个数据包,同一数据包的不同分片共享相同标识 便于重组 |
| 标志 | 3bit | 第一位保留为0;第二位禁止分片(1=不分片,超过MTU则丢弃);第三位更多分片(1=后续还有分片,0=最后一个分片) |
| 片偏移 | 13bit | 指示当前分片在原始数据包中的位置(单位:8字节) |
| 生存时间(TTL) | 8bit | 防止数据包无限循环,每经过一个路由器减1 TTL=0时丢弃并发送 ICMP 超时消息 |
| 协议 | 8bit | 标识上层协议:6=TCP,17=UDP,1=ICMP |
| 首部检验和 | 16bit | 仅校验头部数据完整性,不包括数据部分 |
| 源IP地址 | 32bit | 发送方的 IPv4 地址 |
| 目的IP地址 | 32bit | 接收方的 IPv4 地址 |
| 选项字段 | 可变(最多40字节) | 扩展功能(如记录路由、时间戳),较少使用 |
| 填充 | 可变 | 确保头部长度为4字节的整数倍 |
| 数据 | 可变 | 上层协议数据(TCP段、UDP数据报等) |
版本号到目的IP地址总共占20字节
1.3 TCP/IP协议数据封装过程
| 层级 | 数据单元 | 作用 |
|---|---|---|
| 应用层 | 用户数据 | 应用程序实际要发送的原始数据(如 HTTP 请求、文件内容等) |
| 应用层 | Appl首部 | 应用层协议添加的头部信息(如 HTTP 头、FTP 命令等),用于应用层解析 |
| 传输层 | TCP段 | 将应用数据加上 TCP 首部封装成段,负责端到端的可靠传输、流量控制、顺序保证 |
| 传输层 | TCP首部 | 包含源端口、目的端口、序号、确认号、标志位等,用于建立连接、确认、重传等机制 |
| 网络层 | IP数据报 | 将 TCP 段加上 IP 首部封装成数据报,负责跨网络的寻址和路由转发 |
| 网络层 | IP首部 | 包含源 IP、目的 IP、TTL、协议类型等,用于网络层路由选择和数据报转发 |
| 数据链路层 | 以太网帧 | 将 IP 数据报加上以太网首部和尾部封装成帧,负责同一网络内的物理传输 |
| 数据链路层 | 以太网首部 | 包含目的 MAC 地址、源 MAC 地址、帧类型等,用于局域网内标识设备 |
| 数据链路层 | 以太网尾部 | 通常包含帧校验序列(FCS),用于检测数据在传输过程中是否出错 |
二、wireshark抓包工具
| 项目 | 内容 |
|---|---|
| 解析数据包的作用 | 将网络中抓取的二进制原始数据包,按照 TCP/IP 协议栈逐层拆解,还原成人类可读的协议字段(如源IP、目的端口、标志位等),帮助分析网络通信细节。 |
| 常见使用场景 | ① 网络故障排查(如连接失败、丢包、延迟高) ② 协议分析与学习(观察 TCP 三次握手、HTTP 请求响应过程) ③ 网络安全分析(检测异常流量、恶意攻击、数据泄露) ④ 应用性能调试(分析 API 响应慢、重传过多等问题) ⑤ 开发调试网络程序(验证自己写的 socket 程序收发数据是否正确) |
| 一句话总结 | Wireshark 解析包就是把网络上的“天书”翻译成“人话”,用于排查网络问题、学习协议和调试程序。 |
win连接的是WLIE,linux是Loopback
三、TCP沾包问题及解决方案
| 类型 | 现象 | 原因 |
|---|---|---|
| 正常包 | 发送一次,接收端一次收到完整的一条消息 | 数据大小合适,发送和接收时机匹配 |
| 粘包 | 发送多次,接收端一次收到了多条消息粘在一起 | 发送端多次小数据发送,接收缓冲区积累后一次性读取;或 Nagle 算法合并小包 |
| 拆包 | 发送一次,接收端分多次才收到完整消息 | 发送的数据大于接收缓冲区大小;或 TCP 分段传输(MSS 限制) |
TCP粘包问题
| 分类 | 具体原因 | 说明 |
|---|---|---|
| TCP协议特性 | 面向字节流 | TCP 没有消息边界,数据像流水一样传输,不保留发送时的消息分隔 |
| 缓冲区机制 | 发送方和接收方都有缓冲区,数据在缓冲区中积累,可能导致多条消息合并或拆分 | |
| 发送方行为 | 数据写入方式 | 多次小数据写入,可能被合并成一个 TCP 段发送 |
| Nagle 算法 | 为减少小包数量,延迟发送并合并多个小数据包(默认开启) | |
| 接收方行为 | 读取粒度 | 应用程序一次recv读取的数据长度可能与发送长度不一致,可能读多或读少 |
| 缓冲区读取 | 接收缓冲区有数据时,应用程序可能一次读完所有积压的数据,导致粘包 | |
| 网络传输因素 | 分片与重组 | IP 层可能对大数据包分片传输,接收端再重组,导致应用层看到的数据边界变化 |
| MTU/MSS 限制 | 当发送数据超过 MSS,TCP 会自动分段,导致一条消息被拆成多个包发送 |
| 对比项 | MTU | MSS |
|---|---|---|
| 定义 | 网络接口层所能传输的最大数据包大小 (包含 IP 首部 + TCP 首部 + 数据) | TCP 数据段中数据部分的最大大小 (不含 TCP 首部和 IP 首部) |
| 所在层级 | 网络接口层 / IP 层 | 传输层(TCP) |
| 典型值 | 以太网中通常为 1500 字节 | 通常为 1460 字节(1500 - 20 IP首部 - 20 TCP首部) |
| 计算关系 | MSS = MTU - IP首部大小 - TCP首部大小 | |
| 作用 | 限制单个网络帧能携带的总数据量 | 限制 TCP 段中数据部分的最大大小 |
| 双方协商 | 由网络链路决定,通常无需协商 | TCP 三次握手时双方协商,取较小值 |
| 超出后果 | 需要 IP 分片,降低传输效率 | 超出 MSS 的数据会被 TCP 分段 |
