我們有現有軟件將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()
您的接收器是否需要「綁定」廣播地址或「INADDR_BROADCAST」(255.255.255.255,廣播的「INADDR_ANY」)?也就是說,除了設置'SO_BROADCAST'選項(雙方)之外,就像你已經做的那樣。您是否檢查所有這些套接字系統調用的錯誤/返回代碼? –
@MatthewHall aha,綁定到廣播地址確實有效!我想這意味着Linux會讓你選擇單播還是廣播?我們可以綁定到INADDR_ANY,並在HP-UX上接收單播和廣播數據包。 – goose
是的,這似乎是你必須選擇。我現在已經爲你的問題發佈了一個規範的答案。然而,我對Linux上的行爲與HP-UX的行爲有所不同有些困惑(儘管有人爭辯說爲什麼分離廣播和單播更可取)。對我而言,這表明我們並不知道所有事情,嗯,這是不可接受的。我很想用C編寫一對測試程序來充實Linux上的廣播選項,儘管我沒有HP-UX ......在此之前,希望我的答案能夠涵蓋它。 –