Sockets Linux中AF_UNIX数据报消息的最大大小是多少?

Sockets Linux中AF_UNIX数据报消息的最大大小是多少?,sockets,unix,dns,datagram,Sockets,Unix,Dns,Datagram,目前我达到了130688字节的硬限制。如果我尝试在一条消息中发送任何较大的内容,我会得到一个ENOBUFS错误 我已经检查了net.core.rmem_default、net.core.wmem_default、net.core.rmem_max、net.core.wmem_max和net.unix.max_dgram_qlen sysctl选项,并将它们全部增加,但它们没有效果,因为它们处理的是总缓冲区大小,而不是消息大小 我还设置了SO_SNDBUF和SO_RCVBUF套接字选项,但这与上面

目前我达到了130688字节的硬限制。如果我尝试在一条消息中发送任何较大的内容,我会得到一个ENOBUFS错误

我已经检查了net.core.rmem_default、net.core.wmem_default、net.core.rmem_max、net.core.wmem_max和net.unix.max_dgram_qlen sysctl选项,并将它们全部增加,但它们没有效果,因为它们处理的是总缓冲区大小,而不是消息大小

我还设置了SO_SNDBUF和SO_RCVBUF套接字选项,但这与上面的问题相同。默认套接字缓冲区大小是根据默认套接字选项设置的

我已经查看了内核源代码,其中ENOBUFS在套接字堆栈中返回,但我不清楚它来自何处。唯一似乎返回此错误的地方与无法分配内存有关


最大尺寸实际上是130688吗?如果没有,可以在不重新编译内核的情况下更改吗?

AF\u UNIX SOCK\u数据报/SOCK\u seq数据报需要连续内存。很难找到连续的物理内存,分配失败,在内核日志中记录类似的内容:

udgc: page allocation failure. order:7, mode:0x44d0
[...snip...]
DMA: 185*4kB 69*8kB 34*16kB 27*32kB 11*64kB 1*128kB 1*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3788kB
Normal: 13*4kB 6*8kB 100*16kB 62*32kB 24*64kB 10*128kB 0*256kB 1*512kB 0*1024kB 0*2048kB 0*4096kB = 7012kB
[...snip...]

unix_dgram_sendmsg()
调用
sock_alloc_send_skb()
,它调用
sock_alloc_send_pskb()
,使用
data_len
=0和
header_len
=数据报的大小
sock\u alloc\u send\u pskb()。因此,在当前的Linux上,AF_UNIX套接字似乎不支持分散/聚集。

这是一个巨大的数据报。在我看来,当你有这么大的数据报时,你可能已经使用了TCP。是的,这没有帮助。正如我在帖子中所说的,无论您的wmem设置如何,它都不会让您通过130688发送消息。我有超过32MB的内存,并尝试了许多低于32MB的组合。只是为了增加这一点。这是一种误解,即发送缓冲区和接收缓冲区用于单个消息。缓冲区是所有消息的总内核缓冲区。wmem和qlen sysctl选项实际上会影响发送块的方式和时间。当发送缓冲区填满时(假设没有人接收),当缓冲区中的总字节数超过缓冲区大小或总计数超过qlen时,发送将被阻止。我更好地理解你的观点(和问题)。编辑混乱的评论并投票表决;如果时间允许,我会四处探索,因为我对答案也很感兴趣。我同意这可能是硬限制。只是想找到一些证据,也许还有一些背后的理由。做得很好。这基本上是我在我的痕迹中发现的,但你提供了实际的原因。我想知道为什么数据报会有这个限制,而流却没有?SOCK_流套接字不保留消息边界。另请参阅SOCK_流套接字上的扩展答案,它肯定会保留消息边界。只需将每条消息放入一个单独的流中:创建一个新套接字,连接它,编写消息,按发送方向关闭它,接收回复,然后断开连接。然后重复下一条消息。也就是说,连接支持帧,因为它们明确定义了“流的开始”和“流的结束”信令;它们只是不支持流中的帧。就像SOCK_DGRAM套接字不支持数据报中的帧一样。@Kaz,所以,它们不支持,你必须伪造它。