设置了 mtu 的 TCP 客户端-服务器,碎片数据包问题

网络工程 以太网 网络核心 linux
2022-02-08 04:18:37

我已经编写了 tcp 客户端-服务器,服务器将读取一个套接字,客户端将数据包写入该套接字。

Mtu : 1500,如果大小超过 mtu,数据包将被分片。

案例 1:当我从客户端写入数据包大小 1456、1457、1458、1459、14560 时,在服务器端接收到相同大小的数据包。

案例 2:当我从客户端写入数据包大小 1461 时,收到了相同大小的数据包,但这应该是两个数据包(pkt-1 大小:1460 + pkt-2 大小:1)

在处理碎片时有点困惑,任何人都可以澄清这一点。

编辑:sock = socket(AF_INET, SOCK_STREAM, 0); <== 正在使用的套接字。

2个回答

您混淆了 MTU 和 MSS。

MTU 1500 与以太网有关,因此它包括 IP 和 TCP 标头。

两者的最小大小都是 20,因此 TCP 的 MSS(最大分段大小)在这种情况下是 1500 - 20 - 20 = 1460。

请注意,在使用选项时,IP 标头和 tcp 标头的大小都可以大于 20,因此您可能仍然会遇到消息小于 1460 字节的碎片。

此外,您的数据包可能会穿越具有不同 MTU 的其他网络。VPN 还将添加一个标头,该标头将进一步降低有效 MSS。

当您使用 TCP 套接字时,名称“SOCK_STREAM”表示您不是将单个数据包写入套接字,而是数据流,并且 TCP 处理它的方式对您来说是透明的。因此,如果您将 1461(或 1,000,000)字节写入流,则在另一端您将能够读取 1461(或 1,000,000)字节。TCP 会自动处理分段流操作(这是 MSS 发挥作用的地方)、重新传输丢失的分段、重新排序无序接收的分段等。如果您进行数据包捕获(例如使用 tcpdump或wireshark)然后你会看到(部分),但是对于使用套接字的进程来说,它都是不可见的。