Hy,我想知道是否有可能找出除实验之外的SEQPACKET的最大长度(a-la为(i = 0; i <100 ... 00; i ++)send(...)))。
而且,第二个问题:
如果我收到errno == EMSGSIZE试图发送AF_UNIX SEQPACKET,是否因为最大邮件大小而保证,或者可能还有其他原因?
抱歉我的英文。
答案 0 :(得分:5)
限制来自变量sysctl_wmem_default
。
它可以在proc文件系统中查看:/proc/sys/net/core/wmem_max
在这一点上,不同的Linux版本可能有不同的实现。 但是UNIX域套接字有这种代码:
sk->sk_sndbuf = sysctl_wmem_default;
和
err = -EMSGSIZE;
if (len > sk->sk_sndbuf - 32)
goto out;
所以实际限制为: / proc / sys / net / core / wmem_max减去32 的值。 我不知道这个神奇数字在版本之间有多大变化。 / proc / sys / net / core / wmem_max的值似乎因可用的ram页面而异。
在我的linux框中,值为105472.最大数据报大小(使用AF_UNIX和SOCK_DGRAM时)为105440.如果我尝试发送大小为105441的消息,则EMSGSIZE将失败。
答案 1 :(得分:0)
刚刚打开套接字后,您可以使用以下代码进行检查:
int s = socket(AF_UNIX, SOCK_DGRAM, 0); // or SOCK_SEQPACKET
int dgram_max_size = 0;
socklen_t optlen = sizeof(dgram_max_size);
int r = getsockopt(s, SOL_SOCKET, SO_SNDBUF, &dgram_max_size, &optlen);
if(r != 0) {
printf("error: can't retrieve socket max. size\n");
exit(1);
}
对于任何套接字,都必须在发送数据之前完成,以确保大小为最大。对于数据报套接字,它可能随时都可以工作。对于基于流的套接字,缓冲区可能会在您写入时缩小,并随着数据的发送而增长。
注意:正如 SKi 所提到的,大小可能相差几个字节。 32 可能是数据包头。因此,您的数据包数据可能仅限于 dgram_max_size - 32
。