ZeroMQ的bind和connect

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZeroMQ的bind和connect相关的知识,希望对你有一定的参考价值。

参考技术A

需求描述:

API服务器,采用异步IO实现并发,故每个API的执行需要非阻塞,否则会造成整个服务会不可用。有若干API是CPU-intensive的,需要较长执行时间,故希望将其执行任务从服务主服务进程detach。

架构设计:

考虑采用ZeroMQ来detach任务执行和API服务主进程。
使用ZeroMQ的PUSH/PULL模型。API主进程为producer(PUSH),worker进程为consumer(PULL)。

有趣的地方是,producer和consumer可以前者bind后者connect,也可以前者connect后者bind。在这个应用场景中,producer要使用connect,而consumer要bind。而不是相反。否则,一旦worker进程没有启动,那么API主进程的send就会阻塞。

坑:
1、producer bind而consumer connect,导致当worker进程未启动时,API主进程在send时会阻塞,从而阻塞所有服务。
2、worker使用了fork来服务多个PUSH/PULL通道。ZeroMQ socket的创建和连接需要在子进程中进行,而不能在父进程中完成然后在子进程中复制句柄。这一想象中或许可以工作的做法其实并不可行。

我可以在同一个套接字描述符上调用 bind() 然后 connect() 吗?

【中文标题】我可以在同一个套接字描述符上调用 bind() 然后 connect() 吗?【英文标题】:Can I call bind() and then connect() on same socket descriptor? 【发布时间】:2019-06-12 15:18:41 【问题描述】:

只是一个关于使用 C/C++ 在 Windows 应用程序中进行网络套接字编程的奇怪问题:

如何告诉connect() 函数使用特定的源 IP 和源端口值?

创建套接字后,应用程序使用sockaddr 结构调用connect() 到远程IP 和端口。

connect() 函数在内部为连接选择源 IP 和端口。

与其让系统决定 connect() 的源 IP 和/或端口,不如让应用程序负责决定绑定到哪个源 IP 和/或端口。

【问题讨论】:

"If socket s, is unbound, unique values are assigned to the local association by the system, and the socket is marked as bound." 如果您想指定使用哪个接口/端口组合,您需要调用bind "让应用程序负责决定要绑定的源端口或 IP" -- 请注意,尽管确实可能有理由将这种方法与您的套接字一起使用要去connect(),他们充其量是罕见的。这种连接的源端口通常在应用程序级别并不重要,并且源 IP 很少有很多选项(除非机器正在连接到自己)。 【参考方案1】:

bind() 请求未使用的端口,以便它可以声明它并成为服务器,而connect() 想要一个已经在使用的端口,因此它可以连接到它并与服务器通信。

正如用户 stark 所说,如果您想指定要使用的接口/端口组合,则需要调用 bind,尽管如果您希望下次调用将其绑定到随机可用端口号,您可以选择退出bind() 调用,因为客户端不一定必须具有固定的端口号。

在调用connect() 之前可以要求内核选择特定端口,但如果我可能会问 - 为什么你不想让内核分配源端口,据我所知这不是最佳实践。

【讨论】:

我想到了几个用例:可以将套接字绑定到接口而不绑定到端口(此处将在调用 connect 时选择端口。)。此外,在 P2P 网络中,需要在调用 connect 之前显式分配端口以启用 NAT 穿越。【参考方案2】:

如何告诉 connect() 函数使用特定的源 IP 和源端口值?

为此使用套接字库的bind() 函数。是的,您可以在connect() 之前调用bind() 以获得传出套接字。这对于 UDP 和 TCP 套接字都是完全合法的操作。

【讨论】:

【参考方案3】:

是的,你可以。 确实有这样做的理由:如果您的路由策略使您的连接从一个不是您想要使用的 IP 地址建立,您可以在多宿主/路由主机中强制通过bind(2) 系统调用将特定IP 地址作为源。另一个用途是为连接指定一个固定的源端口,但这不像以前的情况那样常见。

但请注意:您只能选择您拥有的已配置 IP 地址之一,而不是您可以想象的任何地址。

【讨论】:

以上是关于ZeroMQ的bind和connect的主要内容,如果未能解决你的问题,请参考以下文章

ZeroMQ 反转 PUB/SUB 的问题

为啥 zeromq 在本地主机上不起作用?

WCF扩展之实现ZeroMQ绑定和protocolBuffer消息编码实现IRequestChannel(2016-03-15 12:35)

PyZMQ ( ZeroMQ ) - 如何从 SUB 套接字获取订阅密钥?

zeromq 学习和python实战

ZeroMQ 和 Sails.js