You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用tcpdump捕获TCP/IP分片?Python分片异常排查

TCP分片排查:recv缓冲区大小与DF标志疑问

问题背景

已知网络MTU为1500字节,TCP的MSS为1460字节。我理解当recv函数缓冲区大于1460字节时TCP会分片,于是编写了简单的回显程序,想用tcpdump查看分片情况,但发现缓冲区较小时没有分片显示,直到缓冲区约20K时才出现分片。

按8192字节缓冲区计算,理论上应该分为1460*5 + 892的分片,但实际tcpdump截图中的情况并非如此,我怀疑是否由DF(Don't Fragment)标志导致,想知道Python默认是否设置了该套接字选项?

测试代码

服务端代码

import socket
import sys
import os

addr = ('10.0.0.2', 10086)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(addr)
server.listen(5)

while True:
    connfd, addr = server.accept()
    print 'connection ip:', addr
    data = connfd.recv(8192);

客户端代码

import socket
import os
import sys

addr = ('10.0.0.2', 10086)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(addr)

data = '';
for num in range(0,8192):
    data += '1'
client.sendall(bytes(data))

使用的tcpdump命令

sudo tcpdump -i lo port 10086 -s 1514 -v

问题解答

先帮你理清几个容易混淆的关键概念,再逐个解答你的疑问:

1. 核心概念纠正:TCP不分片,分片是IP层的行为

TCP会根据MSS(最大段大小,这里是1460)拆分应用层数据,发送多个TCP段;而IP分片是当IP数据包大小超过接口MTU时,IP层把数据包拆分成多个小数据包的行为。这两者是完全不同的机制,你看到的tcpdump输出里的“多段”,大概率是TCP分段,而非IP分片。

2. 为什么小缓冲区时看不到“分片”?

你用的是回环接口(lo),Linux系统里回环接口的默认MTU是65536,远大于1500。哪怕TCP发送几个MSS大小的段,整个IP数据包的大小也远低于回环MTU,所以IP层完全不需要分片。而你说的“20K左右才出现分片”,其实是TCP因为滑动窗口、Nagle算法等机制,开始发送更大的批量数据,产生了更多TCP段,而非IP分片。

3. Python套接字默认的DF标志设置

在Linux系统上,Python的socket模块默认不会开启DF标志(对应IP_DONTFRAG套接字选项)。你可以用一行代码验证:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 查看IP_DONTFRAG选项(Linux上该选项的编号是16)
print(s.getsockopt(socket.IPPROTO_IP, 16))

默认返回0,表示DF标志未设置,IP层有权对超过MTU的数据包进行分片。

4. 为什么8192字节数据没有按预期分段?

这是TCP的传输机制导致的:

  • Nagle算法:默认开启的Nagle算法会合并小的TCP段,直到积累到足够大小(比如接近MSS)或者收到对端的ACK才发送,这会让实际发送的段数量和大小和预期不符。
  • 滑动窗口:TCP的滑动窗口大小会影响发送端一次能发送的数据量,可能导致段的拆分方式变化。
  • 系统TCP参数:比如tcp_max_segment等系统参数也会影响实际的段大小。

如果真的想测试IP分片,建议:

  • 切换到物理网络接口(比如eth0),确保该接口的MTU是1500。
  • 构造一个超过MTU的IP数据包(比如通过UDP发送大于1472字节的数据,因为UDP头部8字节+IP头部20字节=28,1500-28=1472),这样就能看到IP分片了。

内容的提问来源于stack exchange,提问作者Tony Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:07:46