与经典 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 框架的核心概念:
我正在用 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 框架的核心概念: