关于Unix:最大缓冲区长度用于sendto?

关于Unix:最大缓冲区长度用于sendto?

Maximum buffer length for sendto?

如何获取作为UDP端口打开的套接字可以传递给sendto(..)调用的最大字节数?


使用getsockopt()。该站点对您可以检索的用法和选项进行了很好的分类。

在Windows中,您可以执行以下操作:

1
2
3
int optlen = sizeof(int);
int optval;
getsockopt(socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (int *)&optval, &optlen);

对于Linux,根据UDP手册页,内核将使用MTU发现(它将检查此处和目标之间的最大UDP数据包大小是多少,然后选择),或者如果MTU发现已关闭,则为"将为接口MTU设置最大大小,并对更大的片段进行分段。如果通过以太网发送,则典型的MTU为1500字节。


在Mac OS X上,发送(SO_SNDBUF)和接收(SO_RCVBUF)的值不同。
这是发送缓冲区(man getsockopt)的大小:

1
getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (int *)&optval, &optlen);

尝试发送更大的消息(在通过本地环回发送的UDP的Leopard 9216八位字节上)将导致"消息过长/ EMSGSIZE"。


由于UDP不面向连接,因此无法指示两个数据包属于同一数据包。结果,您受到单个IP数据包最大大小的限制(65535)。您可以发送的数据要少一些,因为IP数据包的大小还包括IP标头(通常为20个字节)和UDP标头(8个字节)。

请注意,此IP数据包可以分段以适合较小的数据包(例如,以太网约为1500字节)。

我不知道有任何操作系统对此进行进一步限制。

奖金

UDP数据包的

SO_MAX_MSG_SIZE

  • IPv4:65,507字节
  • IPv6:65,527字节

推荐阅读