linux - 即使在 LINUX 上给定的缓冲区足够,套接字 UDP recvfrom 也不适用于大数据包

标签 linux sockets

我正在调用有效地址的 recvfrom api,我正在尝试读取大小为 9600 字节的数据,我提供的缓冲区大小为 12KB,我什至没有获得选择读取事件。 即使推荐的 MTU 大小是 1.5 KB,我也能够发送和接收 4 KB 的数据包。

我正在使用 android NDK (Linux) 进行开发。

请帮忙。我必须设置一个套接字选项来读取大缓冲区吗?

最佳答案

如果你发送一个大于MTU的数据包,它将是fragmented .也就是说,它将被分解成更小的部分,每个部分都适合 MTU。这样做的问题是,即使其中一件丢失了(很可能在蜂窝连接上......),整个数据包实际上也会消失。

要确定是否属于这种情况,您需要在连接的一端(或两端)使用数据包嗅探器。 Wireshark 在 PC 端是一个不错的选择,或者在 android 端使用 tcpdump(你需要 root)。请记住,家用路由器可能会重新组装碎片化的数据包——这意味着如果您从家用路由器/防火墙内部嗅探数据包,您可能看不到任何碎片到达,直到所有碎片都到达路由器(很明显,如果有些碎片正在失去了这不会发生)。

当然,更好的选择是简单地确保您始终发送小于 MTU 的数据包。碎片化几乎从来都不是正确的做法。请记住,MTU 可能会随着服务器和客户端之间路径的不同跃点而变化 - 您可以使用小于 1500 的常见选择(1400 应该是安全的),或者尝试通过 setting the MTU discovery flag on your UDP packets 进行探测。 (通过 IP_MTU_DISCOVER)并且始终发送小于 getsockoptIP_MTU 选项返回的值(包括重传!)

关于linux - 即使在 LINUX 上给定的缓冲区足够,套接字 UDP recvfrom 也不适用于大数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11356528/

相关文章:

sockets - Nginx出现 Varnish 错误: failed (24: Too many open files)

c - sys/msg.h 位于哪里?

linux - 在 ubuntu 上使用 "virt-install"创建虚拟机时出现问题,在显示初始信息后挂起

linux - LINUX intel的i3处理器家族名称是什么?

sockets - Unix 域套接字队列详细信息

Python - Twisted 客户端 - 检查 ping 循环中的 protocol.transport 连接

c - Linux C : upon receiving a signal, 是否可以知道发送者的PID?

linux - 根据第一列的第一个字符和长度拆分文件

C# 服务器线程分配

c# - 如何使用套接字在 .NET 4.5 和 .NET 4.0 之间发送数据?