【问题标题】:PF_UNIX socket blocks after sending twelve packets发送 12 个数据包后 PF_UNIX 套接字阻塞
【发布时间】:2016-08-09 08:28:18
【问题描述】:

我这辈子从来没有遇到过这样的事情。

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

最奇怪的事情发生了

from socket import *

a = socket(PF_UNIX, SOCK_DGRAM)

a.connect("SomePathAlreadyBounded")

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

这最多打印 12,然后开始阻塞...并且仅当服务器从套接字缓冲区读取时才解除阻塞...我已经尝试过使用 SO_SNDBUFSO_RCVBUF 下的 setsockopt 选项还没有成功

以前有人遇到过这种问题吗?如果是这样,我该如何解决它....我想强调一个事实,即send 在发送 12 个数据包后开始完全阻塞...不管它们的大小...

【问题讨论】:

  • @molbdnilo 大声笑,不是 UDS,请先阅读问题
  • 好的,但问题仍然存在:为什么不发布您遇到问题的代码?
  • 我现在无法测试它,但是 Linux 手册页在 unix(7) 手册页的 /proc/sys/net/core/ 下记录了一些参数。但是恐怕您将不得不调整一些内核参数以扩展限制,无论如何,您无法完全删除它。
  • @molbdnilo 我现在无法访问我的代码,而且它是一个非常复杂的 cpp 模型,为了证明问题的真实性而发布了太多代码,我发布的 python 代码导致同样的问题

标签: linux sockets unix unix-socket


【解决方案1】:

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

但是当我在我的 FreeBSD 机器上进行测试时,我的行为略有不同:

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

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

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

【讨论】:

  • 我不记得在我的评论中使用过 UDP 这个词
  • 我也专门使用SOCK_DGRAM,因为我想要数据报而不是我的程序中的流,这也发生在SOCK_STREAM中......无论如何我想找到一种方法来禁用这个限制因为我可能有超过 12 个数据包等待内联读取
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
  • 2013-06-04
  • 1970-01-01
  • 2010-10-31
  • 2013-10-15
  • 2012-03-24
  • 1970-01-01
相关资源
最近更新 更多