c - 如何发送大小大于 64 KB 的 UDP 数据包

标签 c sockets networking kernel buffer

我无法发送 IP multicast datagrams大小大于 64 KB(我的实验需要)。我正在通过 10 Gigabit ethernet 直接连接的计算机之间传输数据包链接(中间没有任何跃点,由 traceroute 确认)。

所有计算机都安装了 Ubuntu 12.04。我通过在 /etc/sysctl.conf 中添加以下行来更改读取和写入缓冲区的限制:

net.core.rmem_max=12582912
net.core.wmem_max=12582912
net.core.rmem_default=12582912
net.core.wmem_default=12582912

并使用 sysctl -a 验证更改(在运行 sysctl -p 之后)。我是否需要重新启动才能看到更改? (我正在共享机器,因此并非总是可以重新启动)。
MTU用于发送和接收的接口(interface)在所有计算机中为 9000 字节。我已成功发送大小约为 60 KB 的数据包,对于 100 KB 的数据包,使用 tcpdump 捕获显示数据包甚至没有被发送并且可能被内核丢弃(我在 tcpdump 跟踪中没有看到它们)。

为了能够传输大数据包(最好是 100 MB 左右的大小),我还需要做什么?

最佳答案

UDP 数据报必须适合单个 IP 数据报。 Total Length IP 头中的字段为 16 位,因此最大长度(包括 IP 和 UDP 头)为 65535 字节。 UDP header还有一个 16 位的 Length field 。 UDP Length 字段包括 UDP 报头,而不是 IP 报头,但由于整个 UDP 数据报必须适合 IP 数据包的有效负载,它受 IP 长度的约束。

所以不可能发送大于 64KB 的 UDP 数据报。由于 IP 和 UDP 报头的最小大小分别为 20 和 8 字节,因此有效负载的实际最大量最多为 65507 字节。

如果您需要发送较大的消息,则需要将其分解为多个数据报。或者也许您应该考虑使用不同的传输协议(protocol),例如 TCP(不幸的是,如果您正在执行多播,这是不可能的)。

IPv6 支持 Jumbograms大于 64K。但是你不能在 IPv4 中做到这一点。

关于c - 如何发送大小大于 64 KB 的 UDP 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32512345/

相关文章:

c - 如何避免特定情况下的忙循环

c - for循环中的数字不增加

c - 了解结构及其项目的声明位置

Java Sockets - 挂起从服务器读取数据

http - Lisp 的奇怪 HTTP 问题/错误

c# - 使用 C# 的 TCPIP 网络

python - Ubuntu 上的 Docker 网络主机

c - 遍历多维数组并添加 float

c - 将 double 分为符号、指数和尾数

Java套接字服务器和客户端