繁体   English   中英

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

[英]Sharing multicast receiver ports between Python and Qt

我正在创建一个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)

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

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接收器客户端。 但是,如果我运行一种类型的客户端,则另一种类型的客户端将不会绑定套接字。

我有一个局部解决方案,即在加入多播组后显式调用setsockopt()以在Qt应用程序中重新设置SO_REUSEADDR标志。 这使我可以在启动Qt客户端之后启动Java客户端。 所有客户端都正常接收,但是在启动第一个Java客户端后我无法再启动任何Qt客户端,否则绑定将失败。 如果关闭所有Java客户端,则可以打开更多Qt客户端。 但是,一旦第一个Java客户端绑定,就不再有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类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM