与经典 TCP 套接字通信

Communicating with a classic TCP socket

我正在用 NetMQ(.NET 的 ZeroMQ 实现)编写我的第一个应用程序。

我还需要监听使用传统 TCP 套接字(a.k.a 非 0MQ 套接字)的客户端发送的信息。

我在官方 ZeroMQ 文档 here 中看到了对这种套接字类型可用性的引用(查找 ZMQ_STREAM),但是关于如何使用它的细节很少(并且这也无济于事,.NET API 与 C++ API).

有很大不同

offical NetMQ documentation也没有提到流式套接字类型。

最后,我查看了 Github 上的 NetMQ 测试套件,并在 method RawSocket.

中找到了我问题的部分答案

以下代码片段有效:

using (NetMQContext context = NetMQContext.Create())
{
    using (var routerSocket = context.CreateRouterSocket())
    {
        routerSocket.Options.RouterRawSocket = true;
        routerSocket.Bind("tcp://127.0.0.1:5599");

        byte[] id = routerSocket.Receive();
        byte[] message = routerSocket.Receive();

        Console.WriteLine(Encoding.ASCII.GetString(id));
        Console.WriteLine(Encoding.ASCII.GetString(message));
    }
}

当使用标准 TCP/IP 测试工具时,byte[] 消息被很好地打印出来,例如像这样:

Hello World!

但是byte[] id是这样打印出来的:

 ???♥

换句话说,我不知道id部分是怎么回事。为什么 routerSocket.Receive 被调用了两次? id中包含什么?这是 ZeroMQ/NetMQ 特定的内容,还是此处提取的 TCP/IP 特定信息?

感谢 @Mangist 指出这一点。

答案在 RouterSocket 文档中:

An identity, sometimes called an address, is just a binary string with no meaning except "this is a unique handle to the connection". Then, when you send a message via a ROUTER socket, you first send an identity frame.

When receiving messages a ZMQ_ROUTER 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 messages a ZMQ_ROUTER 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.

Identities are a difficult concept to understand, but it's essential if you want to become a ZeroMQ expert. The ROUTER socket invents a random identity for each connection with which it works. If there are three REQ sockets connected to a ROUTER socket, it will invent three random identities, one for each REQ socket.

这张图片说明了 ID 框架的核心概念: