python - 在 Python 和 Qt 之间共享多播接收器端口

标签 python c++ qt udp multicast

我正在像这样创建一个 Python 2.7 多播监听器:

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', PORT))
groupAddress = 0
for byte in [224, 0, 0, 243]:
    groupAddress = (groupAddress << 8) | byte
packedGroupAddress = struct.pack('LL', socket.htonl(groupAddress), socket.htonl(socket.INADDR_ANY))
s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, packedGroupAddress)

在另一个用 C++ 和 Qt 4.8 编写的应用程序中,我创建了一个多播监听器,如下所示:

QUdpSocket socket;
if (not socket.bind(PORT, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
    qDebug() << "Binding failed:" << socket.error();
}
socket.joinMulticastGroup(QHostAddress("224.0.0.243"));

两者都工作正常,我可以像我想要的那样接收多播数据包。同时运行两者是行不通的。如果我首先启动 Python 应用程序,那么 Qt 会提示:

Binding failed: QAbstractSocket::AddressInUseError

如果我先运行 Qt 版本,则 Python 会抛出异常并带有此(缩写)回溯:

Traceback (most recent call last):
  [...]
  File "/usr/local/lib/python2.7/dist-packages/gdcp/announcer.py", line 196, in _setupSocket
   s.bind(('', PORT))
  File "/usr/lib/python2.7/socket.py", line 224, in meth
   return getattr(self._sock,name)(*args)
socket.error: [Errno 98] Address already in use

我可以并行运行两个版本多次而不会显示此错误,因此地址共享似乎有效。就在我混合使用 Python 和 Qt 套接字时,我得到了这种行为。我正在运行 Ubuntu 14.04,尽管上面的代码片段也应该在 Windows 上运行。我还无法测试 Windows 是否显示相同的问题。

那么,有人找到解决方案或至少解释了为什么它不起作用吗?

最佳答案

我看到在 Red Hat Enterprise Linux 6.5 上使用 Qt 4.8.5 和 Java 8 共享多播接收器端口时出现类似的问题。我可以同时运行多个 Qt 接收器客户端或多个 Java 接收器客户端。但是如果我运行一种类型的客户端,另一种类型将不会绑定(bind)套接字。

我有一个部分解决方案,就是在加入多播组后显式调用setsockopt()重新设置Qt应用程序中的SO_REUSEADDR标志。这让我可以在启动 Qt 客户端之后启动 Java 客户端。所有客户端都正常接收,但在启动第一个 Java 客户端后我无法再启动任何 Qt 客户端,否则绑定(bind)将失败。如果我关闭所有 Java 客户端,我就可以打开更多的 Qt 客户端。但是一旦第一个 Java 客户端绑定(bind),就不能再绑定(bind)更多的 Qt 客户端。很奇怪。

我的 Qt 代码现在看起来像这样:

if (_socket->bind(port, QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint))
{
  if (_socket->joinMulticastGroup(bindAddr))
  {
    int reuse = 1;
    if (setsockopt(_socket->socketDescriptor(), SOL_SOCKET, SO_REUSEADDR,
                  (char *)&reuse, sizeof(reuse)) < 0)
      qDebug() << "setsockopt() failed";
  }
  else
    qDebug() << "joinMulticastGroup() failed";
}
else
  qDebug() << "bind() failed";

我没有 Java 客户端的源代码,但我听说它正在以推荐的方式使用 java.net.MulticastSocket 类。

关于python - 在 Python 和 Qt 之间共享多播接收器端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25424838/

相关文章:

python - Unicode解码错误: 'ascii' codec can't decode byte 0x8b

python - 生成每行重置具有最低 N 值位置的掩码数组

c++ - Qt 表格小部件垂直和水平标题变得不可见

c++ - 根据字体句柄获取字体文件名 (HFONT)

c++ - 为什么这个重载函数是模棱两可的?

c++ - cmake、conan 和 qt hello world 项目构建错误

c++ - Qt - 在工作线程崩溃时将 cv::Mat 转换为 QImage

python - 固定装饰器参数

python - 通过掩码选择 numpy 数组的元素并保留原始尺寸

c++ - 具体类的析构函数