簡體   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