2012-12-02 150 views
10

ローカルサブネット(x.x.x.255)の特定のポート(7125)に定期的にUDPパケットをブロードキャストする既存のソフトウェアがあります。これらのパケットを問題なく受信できる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カーネルはパケットを受信ソフトウェアに渡します。私は数日間Webを検索していて、同じ問題を抱えている人は見つけられていません。何か案は?

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と動作がまったく異なる理由(ブロードキャストとユニキャストの分離が望ましい理由については議論がありますが)には、私は幾分戸惑っています。私には、すべてが分からないことが示唆されています。それはいつものように容認できません。私は、HP-UXを持っていないが、Linux上のブロードキャストオプションを完全に体現するために、Cで2つのテストプログラムを書くことに誘惑されている。それまでは、私の答えはそれをカバーしている。 –

答えて

13

まあ、私はコメントでこの答えを提案し、それが実際には正しい証明しました。私は自分自身のコードでさらにニュアンスを調べたいと思っていますが、これは標準的なケース・クローズです。

両側にSO_BROADCASTソケットオプションを(すでに正しくやっているように)設定することに加えて、あなたはまた、255.255.255.255であるブロードキャストアドレス(例えば、INADDR_BROADCASTのために、受信機を結合して、本質的に同じ役割を果たしなければなりませんユニキャストの場合はINADDR_ANY)。

元のポスターのHP-UX構成では、ユニキャストアドレス(または具体的にはINADDR_ANY)にバインドされたUDPソケットは、ソケットオプションセットSO_BROADCASTで引き続きローカルブロードキャストアドレス宛のすべてのUDPデータグラムを受信しますおよびホストに向けられたユニキャストトラフィックが含まれます。

Linuxでは、これは当てはまりません。 UDPソケットをバインドすると、たとえSO_BROADCASTが有効になっていても、INADDR_ANYになっていても、バインドされたポートでユニキャストとブロードキャストの両方のデータグラムを受信するには不十分です。ブロードキャストトラフィックに別のINADDR_BROADCAST -bound SO_BROADCASTソケットを使用することができます。

+3

私たちにとっての解決策は、実際にはサブネットブロードキャストアドレスにバインドすることでしたが、INADDR_BROADCASTではバインドしませんでした。また、ブロードキャストではなくユニキャストを受信するシミュレート環境を実行するので、これは究極の解決策ではありません。ただし、 'INADDR_BROADCAST'を編集した場合は、チェックマークをクリックします。 – goose

+0

好奇心の外に、これはどこに文書化されましたか? – Clay

関連する問題