2012-12-02 77 views
10

我們有現有軟件將UDP數據包週期性廣播到本地子網(x.x.x.255)上的特定端口(7125)。我們有在HP-UX(11.11)上運行的監控軟件,能夠接收這些數據包沒有問題。但是,將監控軟件移植到Linux(RHEL 6.1)後,我們發現它不會收到廣播數據包。 tcpdump顯示到達Linux主機的數據包,但內核不會將它們發送到我們的軟件。在Linux上接收UDP廣播數據包

我一直在使用模擬套接字API的幾個python 2.x腳本來調用監視軟件用來測試不同的場景。如果發送方使用單播(10.1.0.5),而不是廣播(10.1.0.255),則Linux內核將數據包傳遞給接收方軟件。我一直在網上搜索幾天,並沒有發現任何人有同樣的問題。有任何想法嗎?

receiver.py

from __future__ import print_function 
import socket 

localHost = '' 
localPort = 7125 
remoteHost = '10.1.0.5' 
remotePort = 19100 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 
s.bind((localHost, localPort)) 
s.connect((remoteHost, remotePort)) 
print('Listening on {0}:{1} for traffic from {2}:{3}'.format(localHost, localPort, remoteHost, remotePort)) 
data = s.recv(1024) 
print('Received: {0}'.format(data)) 
s.close() 

sender.py

from __future__ import print_function 
import socket 
import time 

localHost = '' 
localPort = 19100 
remoteHost = '10.1.0.255' 
remotePort = 7125 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 
s.bind((localHost, localPort)) 
s.connect((remoteHost, remotePort)) 
data = 'sending this from {0}:{1} to {2}:{3}'.format(localHost, localPort, remoteHost, remotePort) 
print(data) 
print('2') 
time.sleep(1) 
print('1') 
time.sleep(1) 
s.send(data) 
print('sent at {0}'.format(time.ctime())) 
s.close() 
+2

您的接收器是否需要「綁定」廣播地址或「INADDR_BROADCAST」(255.255.255.255,廣播的「INADDR_ANY」)?也就是說,除了設置'SO_BROADCAST'選項(雙方)之外,就像你已經做的那樣。您是否檢查所有這些套接字系統調用的錯誤/返回代碼? –

+0

@MatthewHall aha,綁定到廣播地址確實有效!我想這意味着Linux會讓你選擇單播還是廣播?我們可以綁定到INADDR_ANY,並在HP-UX上接收單播和廣播數據包。 – goose

+0

是的,這似乎是你必須選擇。我現在已經爲你的問題發佈了一個規範的答案。然而,我對Linux上的行爲與HP-UX的行爲有所不同有些困惑(儘管有人爭辯說爲什麼分離廣播和單播更可取)。對我而言,這表明我們並不知道所有事情,嗯,這是不可接受的。我很想用C編寫一對測試程序來充實Linux上的廣播選項,儘管我沒有HP-UX ......在此之前,希望我的答案能夠涵蓋它。 –

回答

13

好吧,我建議在評論這個答案,並在實踐中證明是正確的。我想用我自己的代碼進一步調查周圍的細微差別,但這是規範的情況。

除了設置在兩側的SO_BROADCAST套接字選項(因爲你已經做正確),則還必須綁定您的接收到廣播地址(例如,INADDR_BROADCAST,這是255.255.255.255,基本上起到同樣的作用作爲單播的INADDR_ANY)。

顯然,在原來的海報,綁定到單播地址(或INADDR_ANY,特別是)一個UDP套接字的HP-UX配置,但是與SO_BROADCAST套接字選項組仍然將接收所有的UDP數據報給當地的廣播地址以及針對主機的單播流量。

在Linux下,情況並非如此。綁定UDP套接字,即使SO_BROADCAST已啓用,至INADDR_ANY也不足以接收綁定端口上的單播和廣播數據報。對於廣播流量,可以使用單獨的INADDR_BROADCAST套接字SO_BROADCAST套接字。

+3

我們的解決方案實際上是綁定到子網廣播地址,而不是'INADDR_BROADCAST'。另外,我們運行一個模擬環境,我們希望接收單播而不是廣播,所以這不是最終的解決方案。但是,如果您編輯了'INADDR_BROADCAST',我會點擊複選標記。 – goose

+0

出於好奇,這是記錄在任何地方嗎? – Clay