ZeroMQ:zmq_errno():156384763---ZeroMQ REQ/REP

ZeroMQ:zmq_errno():156384763—ZeroMQ REQ/REP

ZeroMQ简介

以下是ZeroMQ的自我介绍:“它提供了跨进程内、进程间、TCP和多播等各种传输传输原子消息的套接字。可以使用扇出、发布-订阅、任务分发和请求-应答等模式连接N-to-N套接字。它的速度足以成为集群产品的组成部分。它的异步I/O模型为您提供可伸缩的多核应用程序,作为异步消息处理任务构建。它有许多语言api,可以在大多数操作系统上运行。”
简单来说,ZeroMQ可以简单的理解为升级版的Socket,自带消息队列,自带大数据发送和接收的处理,自带内存管理,本人选择ZeroMQ也是为了简化Socket编程部分。
ZeroMQ官网:ZeroMQ
ZeroMQ C++ API:CPPZMQ

错误简介

[ zmq_errno():156384763 ] 对应的错误解释为:“ zmq_send()/zmq_recv() 函数当前无法对这个socket进行操作,因为这个socket处在与此操作不适当的状态。这个错误可能出现在那些在几种状态之间进行切换的socket上,比如ZMQ_REP。请参照zmq_socket(3)函数部分的消息模式部分以获取更多信息”

简言之,这个错误大多数发生在使用REP (reply) socket和REQ (request) socket的程序中
ZeroMQ对REP socket和REQ socket有严格的限制:承担 服务器 角色的 REP (reply) socket 被严格限制为:接收一个请求后,必须先回复一个请求,然后才能接收下一个请求。也就是说,使用REP (reply) socket的程序,必须在socket.recv()之后立刻调用一个socket.send()对请求进行回复,然后才能进行下一次socket.recv(),即使回复的消息内容为空,也需要进行回复。

同理,承担 客户端 角色的 REQ (request) socket 被严格限制为 发送一个请求后,必须先接收一个来自服务器的回复,然后才能进行下一次请求。与服务器正好相反,使用REQ (request) socket的程序,必须在socket.send()之后立刻调用一个socket.recv()对请求进行接收,然后才能进行下一次socket.send(),即使接收到的消息内容为空,也需要进行接收。

进一步

上述限制是对于一个ZeroMQ Sokcet对象(C++或其它面向对象语言)/ZeroMQ Socket句柄(C或其他过程化语言)的,如果你在一个程序中同时创建了多个 REP (reply) socket(服务器)REQ (request) socket(客户端),对 单个 ZeroMQ Sokcet对象/句柄,仍然需要遵守上述规则,但是 多个 ZeroMQ Sokcet对象/句柄之间则不需要遵守上述规则。即:如果我有两个REP (reply) socket(服务器) s o c k e t 1 socket_{1} socket1 s o c k e t 2 socket_{2} socket2,对于 s o c k e t 1 socket_{1} socket1 s o c k e t 2 socket_{2} socket2单个对象/句柄而言,仍然需要在接收后进行回复才能进行下一次接收,但是两个句柄之间没有这种约束, s o c k e t 1 socket_{1} socket1接收完之后, s o c k e t 2 socket_{2} socket2可以立马接收,而不需要等待 s o c k e t 1 socket_{1} socket1回复后才能接收。

难以察觉的错误

这个错误在 多线程 服务器或客户端中会变的难以发现,最常见的就是,服务器或客户端中拥有 N 个独立的线程,但只有一个ZeroMQ Socket对象/句柄,同时,这 N 个独立的线程都可能使用这个对象/句柄来发送或接收消息,这个时候就会出现 程序时好时坏,有时候能成功运行,有时候则会出现上述错误,建议多线程程序每个线程分配一个REP (reply) socket(服务器)REQ (request) socket(客户端),或使用其他类型的API。

猜你喜欢

转载自blog.csdn.net/Online_exspiravit/article/details/127565727
今日推荐