ZeroMQ 内部是如何连接和绑定工作的

How does ZeroMQ connect and bind work internally

我正在试验 ZeroMQ。我发现在 ZeroMQ 中,connectbind 先发生并不重要。我试着查看 ZeroMQ 的源代码,但它太大了,找不到任何东西。

代码如下

# client side
import zmq
ctx = zmq.Context()
socket = ctx.socket(zmq.PAIR)
socket.connect('tcp://*:2345') # line [1]
# make it wait here

# server side
import zmq
ctx = zmq.Context()
socket = ctx.socket(zmq.PAIR)
socket.bind('tcp://localhost:2345')
# make it wait here

如果我先启动客户端,服务器还没有启动,但神奇的是代码没有在第 [1] 行被阻塞。此时,我检查了 ss 并确保客户端没有在任何端口上侦听。它也没有任何开放的连接。然后我启动服务器。现在服务器正在侦听端口 2345,客户端神奇地连接到了它。我的问题是客户端如何知道服务器现在在线?

提问的最佳地点是 ZMQ mailing list, as many of the developers (and founders!) of the library are active there and can answer your question directly, but I'll give it a try. I'll admit that I'm not a C developer so my understanding of the source is limited, but here's what I gather, mostly from src/tcp_connector.cpp(其他传输包含在各自的文件中,可能表现不同)。

Line 214 启动 open() 方法,这里看起来是正在发生的事情的核心。

要回答关于代码为何未在行 [1] 处被阻止的问题,请参阅 line 258. It's specifically calling a method to make the socket behave asynchronously (for specifics on how unblock_socket() works you'll have to talk to someone more versed in C, it's defined here)。

line 278, it attempts to make the connection to the remote peer. If it's successful immediately, you're good, the bound socket was there and we've connected. If it wasn't, on line 294 上它将错误代码设置为 EINPROGRESS 并失败。

为了看看接下来会发生什么,我们回到start_connecting() method on line 161。这是调用 open() 方法的地方,也是使用 EINPROGRESS 错误的地方。我对这里发生的事情的最好理解是,如果一开始它没有成功,它会异步地再次尝试,直到找到它的对等方。