【问题标题】:ZeroMQ cannot set ZMQ_RATE - Invalid Argument (using EPGM or PGM Multicast)ZeroMQ 无法设置 ZMQ_RATE - 无效参数(使用 EPGM 或 PGM 多播)
【发布时间】:2016-07-01 19:45:30
【问题描述】:

我无法在 ZeroMQ 多播套接字上通过 ZMQ_RATE(默认为非常低的 100 kbits/sec)设置最大速率 - 对 zmq_setsocketopt() 的调用失败(使用 @ 987654324@ 语言)。

我需要更高的速率,因为我的应用程序涉及流式视频。

任何人都可以对此有所了解 - 这是复制问题的精简代码

void* _context;
void* _responder;

_context    = zmq_ctx_new ();
_responder  = zmq_socket ( _context, ZMQ_SUB );

int64_t val = 100000;
int rc;

rc          = zmq_setsockopt( _responder, ZMQ_RATE, &val, sizeof(int64_t) );
int ze2     = zmq_errno ();

int           major,  minor,  patch;
zmq_version( &major, &minor, &patch );

printf( "DIAG[zmq_setsockopt() API:%d.%d.%d] RC: (%d) ~ Errno: (%d) ~ Error:(%s)\n",
        major,
        minor,
        patch
        rc,
        ze2,
        zmq_strerror( ze2 )
        );

上面的输出是:

     DIAG[zmq_setsockopt() API:4.0.4] RC: (-1) ~ Errno: (22) ~ Error: (Invalid argument)

如果我将套接字类型更改为 ZMQ_PUB,我也会收到错误消息。
我已经测试了从 1 到 100000 不同数量级的许多速率,都以相同的方式失败。

版本为 4.0.4,在 Windows 7 上运行

【问题讨论】:

  • API 版本很重要。它决定是否所有流量都流向每个 SUB 端,如果仍在使用版本,则在每个 SUB 接收节点上处理 ZMQ_SUBSCRIBE 主题过滤器(即使没有 SUB 订阅任何 PUB 主题,也要保持传输和处理开销)。您可以通过仔细调整 Context 属性和 ioThread 关联映射来以某种方式对此进行调整,但如果其他设计约束允许,则值得更新。您对流式应用程序的研究似乎是处理密集型的,因此任何分布式处理的 IO 调整都需要非常小心。
  • 谢谢我根据以下回复进行了编辑 - 版本是 4.0.4。我会将 ZeroMQ 升级到最新版本,看看这是否仍然存在,尽管在生产中一切都在运行 4.0.4,所以我不愿意这样做,以防出现其他值得一试的问题
  • 好吧,在某些项目中,由于缺少某些分布式系统节点上的较新语言绑定,我不得不保持与 2.1.11 版本一样旧的 API 兼容性。 4.0.4 应该不是问题。 (+ 参考。更新如下)

标签: zeromq multicast


【解决方案1】:

zmq_setsockopt()API 仅具有以下可能的错误状态:

EINVAL
请求的选项option_name 未知,或者请求的option_lenoption_value 无效。

ETERM
与指定套接字关联的 ØMQ 上下文已终止。

ENOTSOCK
提供的套接字无效。

EINTR
操作因传递信号而中断。

我的嫌疑人是 EINVAL
并且将代码更接近 MCVE
的最小步骤是执行此操作并发布终端输出:

void* _context;
void* _responder;

assert ( ZMQ_RATE == 8 );                           # mod.000: validate zmq.h compliance
assert ( ZMQ_SUB  == 2 );                           # mod.000: validate zmq.h compliance

_context    = zmq_ctx_new ();

assert ( _context );                                # mod.000: validate <context> instance

_responder  = zmq_socket ( _context, ZMQ_SUB );

assert ( _responder );                              # mod.000: validate <socket> instance

int val     = 123;                                  # mod.000: enforce (int)

int rc      = zmq_setsockopt( _responder, ZMQ_RATE, &val, sizeof(val) );
int ze2     = zmq_errno ();

int           major,  minor,  patch;
zmq_version( &major, &minor, &patch );

printf( "DIAG[zmq_setsockopt() API:%d.%d.%d] RC: (%d) ~ Errno: (%d) ~ Error: (%s)\n",
         major,
         minor,
         patch
         rc,
         ze2,
         zmq_strerror( ze2 )
         );

UPDATE 000.INF:

来自ZeroMQ v3.x,当使用连接协议(tcp://ipc://)时,过滤发生在发布者端。使用 epgm:// 协议,过滤发生在订阅方。

ZeroMQ v2.x 中,所有过滤都发生在订阅方。

UPDATE 000.w7.CHECK:

根据 http://technet.microsoft.com/en-us/library/cc957547.aspx
可能需要检查 REGISTRY 的 {key: value}-presence/state HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IGMPLevel
不要错过或0
这是“答案”的一种病态部分,但w7可能禁止多播( zmq_errno() 不应该自我证明,但比起在移动的沙地上建造,确定坚实的基础似乎更好,不是吗?)。


UPDATE 001.w7.Final_step:

如果指示的 EINVAL 错误也在基于 linux 的系统上返回,重新测试相同场景,fill a ZeroMQ BugReport

否则,问题解决与w7相关,请咨询您的本地主机管理员解决问题。

pgm 传输实现需要访问原始 IP 套接字。在某些操作系统上,此操作可能需要额外的权限。鼓励不需要与其他 PGM 实现直接互操作的应用程序使用 epgm 传输,而不需要任何特殊权限。

【讨论】:

  • 谢谢您 - 我将编辑问题以合并。输出是 DIAG[zmq_setsockopt() API:4.0.4] RC: (-1) ~ Errno: (22) ~ Error: (Invalid argument) 所以它确实是 EINVAL
  • 虽然这对于代码大师来说可能看起来晦涩难懂,但您是否介意使用该死的 hack 来进一步明确消除根本原因 - 根据int val = 123;rc = ... sizeof(val)); 中的 API 文档使用显式 int 类型和assert ( _responder ); assert ( ZMQ_RATE == 8 ); ?
  • 感谢您随后的编辑 000.w7.CHECK。我应该澄清一下,我可以在一对 w7 机器之间通过多播传输数据——但只能以 100kbit/秒的速度传输。我试图在 EPGM 通道上发布大约 5MByte/sec 的 JPEG 数据,但网络分析显示线路上的数据以 100kbit/sec 的速率传输。在 SUBing 机器上(缓慢)接收这些数据包表明多播正在工作但正在受到限制,这就是为什么我试图在源和目标上更改此套接字选项,因为它的默认设置明显设置为 100kbit/sec。
  • 感谢您的编辑 000.INF - 这些断言对于检查来说是个好主意,但是它们都通过了,即使将 sizeof(val) 替换为 setsockopt 我也会得到相同的失败结果来自 0MQ。同样在我的原始帖子中,我使用 int64_t 而不是 int 作为选项值 - 这是 API 文档要求的(这是一个 win32 项目,因此我平台上的 int 更短)但无论如何这两种类型的结果相同错误。此检查也在 4.0.4 windows 7 上执行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
  • 2014-07-14
  • 1970-01-01
相关资源
最近更新 更多