You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

VirtualBox中OpenWrt虚拟机ZeroMQ订阅端无法接收消息排查

问题:OpenWrt虚拟机间ZeroMQ发布订阅无法接收消息

环境背景

我在VirtualBox中部署了两台OpenWrt 18.06.4虚拟机A(发布端/服务器)和B(订阅端/客户端),打算用ZeroMQ实现发布-订阅消息传输。采用经典的psenvpub(发布端)和psenvsub(订阅端)逻辑,本地主机运行完全正常,但迁移到虚拟机后遇到异常:

  • 编译了两个订阅端版本,分别监听A的NAT网络IP 10.0.1.4Host-Only网络IP 192.168.56.10
  • 发布端能正常执行send函数并打印已发送消息,但订阅端始终收不到消息(返回null

网络配置

VirtualBox配置了两种网络:

  • NAT Network:10.0.1.0/24
  • Host-Only网络:192.168.56.1/24
    两台虚拟机都配置了Host-Only适配器(vboxnet0)和NAT网络适配器,且虚拟机间可互相ping通。

虚拟机A(发布端)网络配置

config interface 'loopback'
    option ifname 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'
config globals 'globals'
    option ula_prefix 'fd03:84ea:bc33::/48'
config interface 'lan'
    option ifname 'eth0'
    option proto 'static'
    option ipaddr '192.168.56.10'
    option netmask '255.255.255.0'
config interface 'wan'
    option ifname 'eth1'
    option proto 'dhcp'
# NAT网络(wan)当前IP为10.0.1.4

虚拟机B(订阅端)网络配置

config interface 'loopback'
    option ifname 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'
config globals 'globals'
    option ula_prefix 'fdea:4700:64aa::/48'
config interface 'lan'
    option ifname 'eth0'
    option proto 'static'
    option ipaddr '192.168.56.20'
    option netmask '255.255.255.0'
config interface 'wan'
    option ifname 'eth1'
    option proto 'dhcp'
# NAT网络(wan)当前IP为10.0.1.5

可能的问题与解决方案

1. 发布端绑定地址错误(最常见原因)

如果发布端代码里zmq_bind用的是tcp://127.0.0.1:5568tcp://localhost:5568,发布端只会监听本地回环接口,其他机器根本无法建立连接。

修复方法:把绑定地址改成tcp://0.0.0.0:5568(监听所有可用网卡),或者指定虚拟机的实际IP(比如tcp://192.168.56.10:5568tcp://10.0.1.4:5568),确保其他机器能接入。

2. OpenWrt防火墙拦截ZeroMQ端口

OpenWrt默认防火墙会严格过滤外来连接,哪怕ping能通,ZeroMQ默认使用的5568端口大概率没被放行。

快速测试:先临时关闭两台虚拟机的防火墙,再测试消息传输:

/etc/init.d/firewall stop

如果关闭后能正常接收,就是防火墙的问题,需要添加永久规则:

  • 方法1:SSH执行命令(临时生效,需保存规则)
# 允许TCP 5568端口的入站连接
iptables -A INPUT -p tcp --dport 5568 -j ACCEPT
# 保存规则避免重启失效
/etc/init.d/firewall save
  • 方法2:修改/etc/config/firewall文件(永久生效),添加如下规则:
config rule
    option name 'Allow-ZeroMQ-PubSub'
    option src '*'  # 允许所有来源,也可指定lan/wan区域
    option proto 'tcp'
    option dest_port '5568'
    option target 'ACCEPT'

然后重启防火墙:

/etc/init.d/firewall restart

3. VirtualBox网络适配器混杂模式设置

虽然虚拟机间能ping通,但Host-Only网络的混杂模式如果没开启,可能影响跨机器消息传输:

  • 打开VirtualBox → 文件 → 主机网络管理器 → 选中vboxnet0 → 修改 → 勾选混杂模式:允许所有 → 确定

4. 编译或ZeroMQ版本问题

检查编译后的二进制文件依赖是否正确:

# 在虚拟机中执行
ldd your_pub_executable
ldd your_sub_executable

如果显示缺失ZeroMQ库,说明编译环境有问题,需要重新用OpenWrt SDK编译,确保静态编译或把依赖库安装到虚拟机中。

5. 抓包验证数据包流向

如果以上方法无效,用tcpdump抓包确认数据包是否到达:

  • 在虚拟机A(发布端)抓Host-Only网卡的包:
tcpdump -i eth0 tcp port 5568
  • 在虚拟机B(订阅端)抓包:
tcpdump -i eth0 tcp port 5568

如果A的抓包看不到B的连接请求,说明网络层面有问题;如果看到连接但B没收到消息,可能是ZeroMQ逻辑或防火墙的问题。


内容的提问来源于stack exchange,提问作者imll

火山引擎 最新活动