tcp - 使用 ZeroMQ ZMQ_STREAM 作为 tcp 客户端。为什么我会收到额外的信息?

标签 tcp zeromq

我有一个使用 ZeroMQ 做各种事情的应用程序,我还想将它用作其他外部连接的 tcp 客户端。

目前,如果外部 tcp-server 发送数据,客户端会收到 5 字节 id、0 字节、5 字节,然后是实际消息。

如何让 ZeroMQ 不发送这些东西?

#include <iostream>
#include <string>
#include <zmq.h>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <thread>


int main()
{
  void *mpSocketContext = zmq_ctx_new();

  /* Create ZMQ_STREAM socket */
  void *mpSerialSocket = zmq_socket(mpSocketContext, ZMQ_STREAM);
  void *mpSocket = mpSerialSocket;
  bool aeBlocking = true;

  std::string asAddress = "127.0.0.1:1236";
  asAddress  = "tcp://" + asAddress;

  std::cout << "tcSerialServerPort::tcSerialServerPort: connecting to " << asAddress << std::endl;

  int rc = zmq_connect(mpSerialSocket, asAddress.c_str());
  if (rc != 0)
    std::cout << "ZMQ ERROR: zmq_connect " <<  zmq_strerror(zmq_errno()) << std::endl;

  uint8_t id [256];
  size_t id_size = 256;
  rc = zmq_getsockopt (mpSerialSocket, ZMQ_IDENTITY, id, &id_size);
  assert(rc == 0);

  while(true)
  {
  zmq_msg_t msg;
  zmq_msg_init(&msg);
  size_t lnBytesReceived = 0;
  std::string lsStr;

  lnBytesReceived = zmq_recvmsg(mpSocket, &msg, aeBlocking ? 0 : ZMQ_DONTWAIT);

  lsStr = std::string(static_cast<const char*>(zmq_msg_data(&msg)),
      zmq_msg_size(&msg));


  std::cout << "Received Bytes=" << lsStr.size() << " Data=" << lsStr << std::endl;

  zmq_msg_close(&msg);

  std::this_thread::sleep_for(std::chrono::seconds(1));
  }


  zmq_close(mpSerialSocket);
  zmq_ctx_destroy(mpSocketContext);

  return 0;
}

最佳答案

第 1 步:不要 panic 。

这很容易——要么停止使用 ZeroMQ,要么开始设计与已发布的 ZeroMQ API 文档兼容的东西。寻求第三种方式仍然是可能的,但人们可能很容易猜到这样一个分支项目将完成什么。

最好让我们开始重新阅读 API 中的设计规则:

为什么我会收到额外的信息? ZeroMQ 发布的 API 说:

Native pattern

The native pattern is used for communicating with TCP peers and allows asynchronous requests and replies in either direction.

ZMQ_STREAM

A socket of type ZMQ_STREAM is used to send and receive TCP data from a non-ØMQ peer, when using the tcp:// transport. A ZMQ_STREAM socket can act as client and/or server, sending and/or receiving TCP data asynchronously.

When receiving TCP data, a ZMQ_STREAM socket shall prepend a message part containing the identity of the originating peer to the message before passing it to the application. Messages received are fair-queued from among all connected peers.

When sending TCP data, a ZMQ_STREAM socket shall remove the first part of the message and use it to determine the identity of the peer the message shall be routed to, and unroutable messages shall cause an EHOSTUNREACH or EAGAIN error.

To open a connection to a server, use the zmq_connect call, and then fetch the socket identity using the ZMQ_IDENTITY zmq_getsockopt call.

To close a specific connection, send the identity frame followed by a zero-length message (see EXAMPLE section).

When a connection is made, a zero-length message will be received by the application. Similarly, when the peer disconnects (or the connection is lost), a zero-length message will be received by the application.

You must send one identity frame followed by one data frame. The ZMQ_SNDMORE flag is required for identity frames but is ignored on data frames.

其余的很明显,遵循用户代码中记录的 API 行为,所有 ZeroMQ 的东西都像 charm 一样工作。

关于tcp - 使用 ZeroMQ ZMQ_STREAM 作为 tcp 客户端。为什么我会收到额外的信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47560213/

相关文章:

ipc - 为什么/何时使用DDS代替ZeroMQ?

python - 使用zeromq在python中进行远程tcp连接

java - 在主机上运行我的 Intellij IDE,我需要 ZeroMQ 以便与 guest 上的后端应用程序通信

sockets - 当服务器套接字接受客户端套接字时到底发生了什么?

java - 强制 TCP 套接字在 Java 中刷新

java - 在套接字中发送停止消息

c++ - 设置 SO_RCVBUF 会减小窗口缩放因子

c - ZeroMQ 的网络诊断示例

c - 如何避免 'C' 中的 TCP 聚合?

multithreading - 在ZeroMQ中从多个线程到zmq_poll()一个REP套接字+ send()安全吗?