2013-03-07 43 views
0

我有一個硬件設備在我的網絡上發送多播數據。我寫了一個接收數據並打印它的python腳本。但是,我發現它只能在我的Windows XP PC上運行,並且在我的Ubuntu Linux 10.04 PC上無法運行。在Linux下,沒有收到任何東西。它只是圍繞while循環,並沒有收到任何數據。我的代碼發佈在下面。你能看出爲什麼這在Linux下無法正常工作嗎?謝謝,Rab。在Linux上使用python接收組播UDP數據報

# 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發送,其他所有人都可以使用我的接收腳本正確接收。但是,只有我的一臺Windows PC能夠從相關硬件設備接收數據。我想知道這是否與以太網適配器或它們的配置有關。這可能是因爲harware設備的IP地址爲0.0.0.0,並且這些以太網適配器和/或我的接收器腳本需要通過這個地址接收消息?在Linux PC上運行Wireshark可以查看來自硬件設備的數據。

+0

通過選票來判斷你應該檢查http:// stackoverflow。com/questions/603852/multicast-in-python – 2013-03-08 13:15:33

+0

@EeroAaltonen我已經檢查過這個帖子,發現代碼可以在我的各種PC之間工作。但是,接收的代碼仍然不會收到我希望分析的硬件設備發送的數據(它使用地址0.0.0.0,我認爲這可能是問題的根源)。 – robhem 2013-03-09 20:48:39

回答

0

嘗試綁定到組播組地址,而不是:

sock.bind((MCAST_ADDR,MCAST_PORT)) 

而且,你不需要設置組播TTL在接收器上,這對發送者,也可選。

+0

'sock.bind((MCAST_ADDR,MCAST_PORT))' 導致錯誤:請求的地址在其上下文中無效。我認爲綁定到0.0.0.0是正確的,因爲這告訴IP層使用所有可用的適配器進行收聽。 – robhem 2013-03-08 10:03:21

+0

我應該在Windows上(而不是在Linux上)添加'sock.bind((MCAST_ADDR,MCAST_PORT))'錯誤的結果。但是,這並沒有解決我的問題。 – robhem 2013-03-08 16:46:06

+0

是的,生存時間僅適用於發件人。謝謝。 – robhem 2013-03-11 10:20:23

0

我打了兩天這個相同的問題。 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設置。我試過了。他們沒有幫助,所以我將它們重置爲安裝默認值。

+0

感謝您的輸入。我會研究這些事情。 – robhem 2013-03-09 23:47:48

+0

Runniing'ip maddr'顯示eth0的組播地址。 – robhem 2013-03-11 15:19:49

+0

如果我嘗試運行'sudo smcroute -d',我得到'MC-Router IPv4已經在使用中',並且'內核不支持多播路由'錯誤。我已經確認內核配置已啓用多播,如鏈接中所述。任何其他方式我可以添加一個IP到eth0?我嘗試了以下方法: 我在'/ proc/sys/net/ipv4/conf/all/rp_filter'中和/ proc/sys/net/ipv4中創建了'rp_filter = 0' conf/default/rp_filter'和'/ etc/sysctl.d/10-network-security.conf'中。 '/etc/sysctl.conf'中也沒有註釋'net.ipv4.ip_forward = 1'。仍然沒有快樂。 – robhem 2013-03-11 15:28:45