我想知道除了试验性方法(例如 for( i=0; i<100...00; i++ ) send( ... );
)之外,是否有可能找到 SEQPACKET
的最大长度。
还有第二个问题:
如果我在尝试发送 AF_UNIX
SEQPACKET
时收到 errno == EMSGSIZE
,那么这是否保证是由于消息大小达到了最大值,或者可能还有其他原因?
我想知道除了试验性方法(例如 for( i=0; i<100...00; i++ ) send( ... );
)之外,是否有可能找到 SEQPACKET
的最大长度。
还有第二个问题:
如果我在尝试发送 AF_UNIX
SEQPACKET
时收到 errno == EMSGSIZE
,那么这是否保证是由于消息大小达到了最大值,或者可能还有其他原因?
限制来自变量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的值似乎会随着可用内存页数而变化。
在我的Linux系统中,该值为105472。当使用AF_UNIX和SOCK_DGRAM时,最大数据报大小为105440。 如果我尝试发送大小为105441的消息,它将失败并显示EMSGSIZE。
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);
}