找出AF_UNIX + SOCK_SEQPACKET最大邮件大小

时间:2011-10-14 10:22:17

标签: c linux sockets unix

Hy,我想知道是否有可能找出除实验之外的SEQPACKET的最大长度(a-la为(i = 0; i <100 ... 00; i ++)send(...)))。

而且,第二个问题:

如果我收到errno == EMSGSIZE试图发送AF_UNIX SEQPACKET,是否因为最大邮件大小而保证,或者可能还有其他原因?

抱歉我的英文。

2 个答案:

答案 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