sendto的最大缓冲区长度?

时间:2020-03-05 18:42:46  来源:igfitidea点击:

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

解决方案

回答

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

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

我不知道任何操作系统会进一步限制这一点。

回答

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

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

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):

getsockopt(袜子,SOL_SOCKET,SO_SNDBUF,(int *)&optval,&optlen);

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