Q : 有没有一种方法我可以利用 ZeroMQ 在这个应用程序中提供相同的行为作为标准插座?
ZeroMQ 是 distributed-systems 的 very smart and rather behaviour-oriented 信号/消息传递平台,而不是套接字。
鉴于您的意图是对 HPC 生态系统有价值,假设/指导使用某种工具的解决方案并且必须尽可能地弯曲它,以便它变得接近类似于原生行为,但是对于其他工具,似乎不是典型的 HPC 级方法。
HPC 代码通常经过精心设计,以提高计算成本效率(并为所有那些今天被允许不为终极性能和硬件资源的使用效率 :o) ) - 在这里,如果有人支付 ZeroMQ 实例化的费用,那么这些非零实例化成本和获得“只是”-a-socket-alike 似乎没有任何好处行为,以成本为代价,具有负面的性能收益,没有对智能的、集群范围的 ZeroMQ 服务(无论是 N+1 还是 N+M 冗余、低延迟智能节点间集群信令、密码学、廉价的以安全为动机的白名单,或任何可能代表任何额外 HPC 级项目利益的东西,这可能证明初始 ZeroMQ 实例化的成本是合理的)。
ZMQ_STREAM 的定义原型可能会提供一些工具,但是,参考。以上
ZMQ_STREAM 类型的套接字用于在使用tcp:// 传输时从非ØMQ 对等方发送和接收TCP 数据。 ZMQ_STREAM 套接字可以充当客户端和/或服务器,异步发送和/或接收 TCP 数据。
接收 TCP 数据时,ZMQ_STREAM 套接字应在将消息传递给应用程序之前,在消息前面添加一个包含原始对等方身份的消息部分。收到的消息在所有连接的对等点之间公平排队。
发送 TCP 数据时,ZMQ_STREAM 套接字应删除消息的第一部分并使用它来确定消息应路由到的对等方的身份,不可路由的消息将导致EHOSTUNREACH 或EAGAIN 错误。
要打开与服务器的连接,请使用 zmq_connect 调用,然后使用 ZMQ_IDENTITY zmq_getsockopt 调用获取套接字标识。
要关闭特定连接,请发送身份帧,后跟零长度消息(请参阅示例部分)。
建立连接后,应用程序将收到一条长度为零的消息。同样,当对端断开连接(或连接丢失)时,应用程序将收到一条长度为零的消息。
您必须先发送一个身份帧,然后再发送一个数据帧。 ZMQ_SNDMORE 标志对于标识帧是必需的,但在数据帧上被忽略。
ZMQ_STREAM 示例:
void *ctx = zmq_ctx_new (); assert (ctx && "Context Instantiation Failed..." );
void *socket = zmq_socket (ctx, ZMQ_STREAM); assert (socket && "socket Instantiation Failed..." );
int rc = zmq_bind (socket, "tcp://*:8080"); assert (rc == 0 && "socket.bind() Failed..." );
uint8_t id [256]; /* Data structure to hold the ZMQ_STREAM ID */
size_t id_size = 256;
uint8_t raw [256]; /* Data structure to hold the ZMQ_STREAM received data */
size_t raw_size = 256;
while (1) {
id_size = zmq_recv (socket, id, 256, 0); assert (id_size > 0 && "Get HTTP request; ID frame and then request; Failed..." )
do {
raw_size = zmq_recv (socket, raw, 256, 0); assert (raw_size >= 0 && "socket.recv() Failed..." );
} while (raw_size == 256);
char http_response [] = /* Prepares the response */
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"Hello, World!";
zmq_send (socket, id, id_size, ZMQ_SNDMORE); /* Sends the ID frame followed by the response */
zmq_send (socket, http_response, strlen (http_response), 0);
zmq_send (socket, id, id_size, ZMQ_SNDMORE); /* Closes the connection by sending the ID frame followed by a zero response */
zmq_send (socket, 0, 0, 0);
}
zmq_close (socket);
zmq_ctx_destroy (ctx);
ZeroMQ zmq_getsockopt() 可以提供 POSIX/SOCKET 描述符,用于低级技巧
ZMQ_FD 选项应检索与指定套接字关联的文件描述符。返回的文件描述符可用于将套接字集成到现有的事件循环中; ØMQ 库应通过使文件描述符准备好读取,以边缘触发的方式通知套接字上的任何未决事件。
从返回的文件描述符中读取的能力并不一定表明消息可以从底层套接字读取或写入;应用程序必须通过随后检索ZMQ_EVENTS 选项来检索实际事件状态。
返回的文件描述符也在 zmq_send 和 zmq_recv 函数内部使用。由于描述符是边缘触发的,因此应用程序必须在每次调用zmq_send 或zmq_recv 后更新ZMQ_EVENTS 的状态。
更明确地说: 在调用 zmq_send 之后,套接字可能变得可读(反之亦然),而不会触发文件描述符上的读取事件。
返回的文件描述符旨在用于 poll 或类似的系统调用only。应用程序绝不能尝试直接读取或写入数据,也不应尝试关闭它。
选项值类型:POSIX 系统上为int,Windows 上为 SOCKET
如需更多details on ZeroMQ tricks,请阅读此处已讨论的解决方案、性能基准、延迟削减细节和其他解决问题的技巧。