发送12个数据包后,UDS会阻塞

时间:2016-08-09 08:28:19

标签: linux sockets unix unix-socket

我以前从未遇到过这样的事情。

我已经在我的C程序中创建了一些简单的uds套接字,(我将使用python显示我的示例,但它最终会调用相同的系统调用/ API)

并且最奇怪的事情发生了

from socket import *

a = socket(AF_UNIX, SOCK_DGRAM)

a.connect("SomePathAlreadyBounded")

for i in range(0,13):
   print(str(i))
   a.send("hey")

这打印最多12个,然后开始阻止...只有当服务器从套接字缓冲区中读取时才解除阻塞....我已经尝试过使用{{1}下的setsockopt选项}和SO_SNDBUF但没有成功

以前有人遇到过这种问题吗?如果是这样我该如何修复....我想强调SO_RCVBUF在发送12个数据包之后开始阻塞的事实...无论其大小如何......

我说的是UDS而不是UDP,我不知道为什么人们认为这个问题是指UDP,不是它的UDS而不是它不是拼写错误,请注意AF_UNIX在我的问题中,对于那些不了解UDS的人来说是一个IPC插座而不是IP SOCKET

1 个答案:

答案 0 :(得分:0)

AF_UNIX上的SOCK_DGRAM不是UDP。您在本地计算机上,没有涉及真正的网络链接。除非发生内核缓冲区短缺,否则将始终以正确的顺序传送数据包。

它比SOCK_STREAM消耗更多资源,因为必须保留数据包边界才能遵守数据报合同。因此,根据底层系统,驱动程序可以在内部缓冲区已满时阻止发送方。

但是当我在我的FreeBSD盒子上测试时,我的行为略有不同:

  • 对于小数据包大小,它最多接受64个数据包
  • 它只接受3 1024个char包
  • 它给出了错误而不是阻止

经过一些更多的研究,FreeBSD和Linux之间的差异以某种方式记录,因为在FB上,如果系统无法分配内部缓冲区,则send可能会因ENOBUFS而失败在Linux手册页中不存在。

TL / DR:发生的情况是正常的:内部缓冲区已满,send阻塞调用方,除非您将套接字置于非阻塞模式。也许某些内核参数允许在Linux上增加12的限制,但总会有一个限制。