2012-12-02 35 views
10

Chúng tôi có phần mềm hiện có định kỳ phát các gói UDP đến một cổng cụ thể (7125) trên mạng con cục bộ (x.x.x.255). Chúng tôi có phần mềm giám sát chạy trên HP-UX (11.11) có khả năng nhận các gói này không có vấn đề gì. Tuy nhiên, sau khi chuyển phần mềm giám sát sang Linux (RHEL 6.1), chúng tôi nhận thấy rằng nó không nhận được các gói phát sóng. tcpdump hiển thị các gói đến máy chủ Linux, nhưng hạt nhân không gửi chúng tới phần mềm của chúng tôi.Nhận các gói phát sóng UDP trên Linux

Tôi đã sử dụng một vài script python 2.x bắt chước API socket gọi phần mềm giám sát sử dụng để kiểm tra các kịch bản khác nhau. Hạt nhân Linux chuyển các gói tin tới phần mềm nhận nếu người gửi sử dụng unicast (10.1.0.5), nhưng không phát sóng (10.1.0.255). Tôi đã tìm kiếm trên web trong vài ngày và không tìm thấy ai có cùng vấn đề. Bất kỳ ý tưởng?

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

Máy thu của bạn không cần phải "liên kết" với địa chỉ quảng bá hoặc 'INADDR_BROADCAST' (255.255.255.255,' INADDR_ANY' phát sóng)? Nghĩa là, ngoài việc thiết lập tùy chọn 'SO_BROADCAST' (trên cả hai mặt), như bạn đang làm. Bạn có kiểm tra mã lỗi/trả về của tất cả các cuộc gọi hệ thống ổ cắm này không? –

+0

@MatthewHall aha, ràng buộc với địa chỉ quảng bá không hoạt động! Tôi đoán điều này có nghĩa là Linux làm cho bạn lựa chọn giữa unicast và phát sóng? Chúng ta có thể liên kết với 'INADDR_ANY' và nhận cả hai gói unicast và broadcast trên HP-UX. – goose

+0

Có, có vẻ như bạn phải chọn. Tôi đã đăng câu trả lời chính thức cho câu hỏi của bạn. Tuy nhiên, tôi phần nào bị lúng túng bởi lý do tại sao các hành vi khác nhau trên Linux từ HP-UX (mặc dù có những lý lẽ về lý do tại sao tách phát sóng và unicast sẽ là thích hợp hơn). Đối với tôi, điều đó cho thấy chúng tôi không biết mọi thứ, và tốt, điều đó không thể chấp nhận được như thường lệ. Tôi bị cám dỗ để viết một vài chương trình thử nghiệm trong C để hoàn toàn xác định các tùy chọn phát trên Linux, mặc dù tôi không có HP-UX ... Cho đến lúc đó, hy vọng câu trả lời của tôi sẽ bao gồm nó. –

Trả lời

13

Vâng, tôi đã gợi ý câu trả lời này trong một chú thích, và nó chứng minh là đúng trong thực tế. Tôi muốn điều tra sắc thái xung quanh hơn nữa với mã của riêng tôi, nhưng đây là trường hợp kinh điển hơn.

Ngoài việc đặt tùy chọn ổ cắm SO_BROADCAST trên cả hai mặt (như bạn đã làm chính xác), bạn cũng phải liên kết người nhận của mình với địa chỉ phát sóng (ví dụ: INADDR_BROADCAST, 255.255.255.255 và về cơ bản phục vụ cùng một vai trò là INADDR_ANY cho unicast). Rõ ràng, trong cấu hình HP-UX của áp phích gốc, một ổ cắm UDP được gắn với địa chỉ unicast (hoặc INADDR_ANY, cụ thể) nhưng với bộ tùy chọn ổ cắm SO_BROADCAST vẫn sẽ nhận được tất cả các gói dữ liệu UDP được gửi đến địa chỉ phát sóng địa phương cũng như lưu lượng truy cập unicast hướng đến máy chủ.

Trong Linux, đây không phải là trường hợp. Ràng buộc một ổ cắm UDP, ngay cả khi SO_BROADCAST -enabled, đến INADDR_ANY là không đủ để nhận cả hai gói dữ liệu unicast và broadcast trên cổng bị ràng buộc. Người ta có thể sử dụng một ổ cắm riêng biệt SO_BROADCAST riêng cho lưu lượng phát sóng.

+3

Giải pháp cho chúng tôi thực sự là liên kết với địa chỉ phát sóng mạng con chứ không phải là 'INADDR_BROADCAST'.Ngoài ra, chúng tôi chạy một môi trường mô phỏng mà chúng tôi muốn nhận unicast thay vì phát sóng vì vậy đây không phải là giải pháp tối thượng. Tuy nhiên, nếu bạn chỉnh sửa 'INADDR_BROADCAST', tôi sẽ nhấp vào dấu kiểm. – goose

+0

Trong số tò mò, liệu tài liệu này có ở bất cứ đâu không? – Clay

Các vấn đề liên quan