我正在试验ZeroMQ。我发现真的很有趣的是,在ZeroMQ中,首先发生connect
或bind
并不重要。我试着查看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,并且神奇地将客户端连接到它。我的问题是客户如何知道服务器现在在线?
答案 0 :(得分:3)
提出问题的最佳地方是ZMQ mailing list,因为图书馆的许多开发人员(和创始人!)都在那里活跃,可以直接回答您的问题,但我会给它一个尝试。我承认我不是C开发人员所以我对来源的理解是有限的,但我收集的内容主要来自src/tcp_connector.cpp(其他传输在各自的传输中都有所涉及)文件,可能表现不同)。
Line 214启动了open()
方法,这里看起来很正常。
要回答有关代码未在第[1]行被阻止的原因的问题,请参阅line 258。它专门调用一种方法使套接字行为异步(有关unblock_socket()
如何工作的具体细节,你必须与更熟悉C的人交谈,它的定义{{3 }})。
在here上,它尝试建立与远程对等方的连接。如果它立即成功,那么你很好,绑定的套接字就在那里,我们已经连接好了。如果不是,则在line 278上将错误代码设置为EINPROGRESS
并失败。
为了看看会发生什么,我们回到line 294。这是调用open()
方法的地方,以及使用EINPROGRESS
错误的地方。我对这里发生的事情的最好理解是,如果一开始它没有成功,它会异步地再次尝试,直到它找到它的同伴。