我正在调用有效地址的 recvfrom api,我试图读取大小为 9600 字节的数据,我提供的缓冲区大小为 12KB,我什至没有收到选择读取事件。甚至强硬推荐的 MTU 大小是 1.5 KB,我能够发送和接收 4 KB 的数据包。
我正在使用 android NDK (Linux) 进行开发。
请帮忙 。我必须设置一个套接字选项来读取大缓冲区吗?
如果您发送的数据包大于 MTU,它将被分片。也就是说,它将被分解成更小的部分,每个部分都适合 MTU。这样做的问题是,即使其中一个丢失了(很可能在蜂窝连接上......),整个数据包也会有效地消失。
要确定是否是这种情况,您需要在连接的一端(或两端)使用数据包嗅探器。Wireshark 是 PC 端的不错选择,或者是 android 端的 tcpdump(你需要 root)。请记住,家庭路由器可能会重新组装碎片数据包 - 这意味着如果您正在从家庭路由器/防火墙内部嗅探数据包,您可能不会看到任何碎片到达,直到它们全部到达路由器(显然,如果有些碎片正在获取失去这不会发生)。
当然,更好的选择是简单地确保您始终发送小于 MTU 的数据包。碎片化几乎从来都不是正确的做法。请记住,MTU 可能在服务器和客户端之间的路径上的不同跃点处有所不同 - 您可以使用小于 1500 的常用选择(1400 应该是安全的),或者尝试通过设置 MTU来探测它UDP 数据包上的发现标志(通过IP_MTU_DISCOVER
),并且始终发送小于选项返回的值getsockopt
(IP_MTU
包括重新传输!)