簡體   English   中英

在Linux上使用python接收多播UDP數據報

[英]Receive multicast UDP datagrams with python on Linux

我有一個在我的網絡上發送多播數據的硬件設備。 我寫了一個python腳本來接收數據並打印它。 但是,我發現它只能在Windows XP PC上運行,而不能在Ubuntu Linux 10.04 PC上運行。 在Linux下,什么也沒收到。 它只是繞過while循環,並且從未收到任何數據。 我的代碼發布在下面。 您能看到任何原因在Linux下無法正常工作嗎? 謝謝,拉布

# Multicast client
# Adapted from: http://chaos.weblogs.us/archives/164
# on 05/03/2013

import socket

ANY = "0.0.0.0" 
MCAST_ADDR = "224.0.33.154"
MCAST_PORT = 31800

# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)

# Allow multiple sockets to use the same PORT number
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

# Bind to the port that we know will receive multicast data
sock.bind((ANY,MCAST_PORT))

# Tell the kernel that we are a multicast socket
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)

# Tell the kernel that we want to add ourselves to a multicast group
# The address for the multicast group is the third param
status = sock.setsockopt(socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(MCAST_ADDR) + socket.inet_aton(ANY));

# setblocking(0) is equiv to settimeout(0.0) which means we poll the socket.
# But this will raise an error if recv() or send() can't immediately find or send data. 
sock.setblocking(0)

while 1:
    try:
        data, addr = sock.recvfrom(1024)
    except socket.error as e:
        pass
    else:
        print "From: ", addr
        print "Data: ", data

這是Windows PC的一些示例輸出:

From:  ('0.0.0.0', 31801)
Data:  EDCP

請注意,遠程硬件設備沒有IP地址,並且正在使用地址0.0.0.0

編輯:我現在發現這也不適用於我的Windows筆記本電腦。 因此,它似乎並不是特定於操作系統的。 此外,我嘗試運行另一個腳本以將多播數據發送到相同的多播地址和端口。 我可以從一台PC發送,而其他所有PC都可以使用我的接收腳本正確接收。 但是,只有我的一台Windows PC能夠從有問題的硬件設備接收數據。 我想知道這是否與以太網適配器或其配置有關。 硬件設備的IP地址為0.0.0.0,並且需要告知這些以太網適配器和/或我的接收方腳本接收具有該地址的消息,這可能與該問題有關嗎? 在Linux PC上運行Wireshark可以查看硬件設備中的數據。

嘗試綁定到多播組地址:

sock.bind((MCAST_ADDR,MCAST_PORT))

另外,您不需要在接收方上設置多播TTL,這是針對發送方的,也是可選的。

我為同一天戰斗了兩天。 Wireshark看到了數據包,但我的代碼沒有。 各種來源的所謂“確定性”答案都沒有對我有用。 密鑰來自https://serverfault.com/questions/163244/linux-kernel-not-passing-through-multicast-udp-packets

運行“ ip maddr”表明與您類似的代碼未將多播地址添加到任何接口。 我強迫它與smcroute添加(請參閱上面的鏈接)。 仍然沒有喜悅。 數據包的源IP為172.22 ...我的接口為172.17 ...我向該NIC添加了172.22地址。 答對了! 現在我的代碼收到了數據包。

現在如何在沒有smcroute的情況下使程序正常工作? 我注釋掉了setsockopt()調用。 仍然有效。 使用smcroute取消鏈接多播地址-失敗。 取消對setsockopt()調用的注釋,並用我的172.22地址替換“ ANY”。 成功!

摘要:

  1. 確保與傳入數據包在同一網段上具有IP。
  2. 在IP_ADD_MEMBERSHIP調用中使用該地址,而不是INADDR_ANY。

如果您只有一個NIC,則可能不需要2)。 我有三個,必須這樣做。

萬一有關系,我使用的是Ubuntu 12.04。 我不需要像其他人所描述的那樣更改任何默認的/etc/sysctl.conf設置。 我試過了 它們沒有幫助,因此我將它們重置為安裝默認值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM