Java Linuxの場合:聞放送メッセージバウンド現地の住所
-
08-07-2019 - |
質問
私は、幾分かの要件が聴ける複数のネットワークインターフェイスからJavaをLinuxマシンを決定いを受けUDPパケットのあるタイプです。出力データあるいはIPアドレスのインタフェース。れる方法はありませJava?
リスニングのワイルドカードアドレス(新DatagramSocket(港))はならないのでがんの放送パケットできるようになるのは地元のIPアドレスインタフェースのいました。聞放送されながら、行きるインターフェイス(新DatagramSocket(ポートアドレス)なの受信にはパケットです。この場合の値のコード例を示す監督-選手コメント:
Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = (NetworkInterface) interfaces.nextElement();
Enumeration addresses = ni.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress address = (InetAddress)addresses.nextElement();
if (address.isLoopbackAddress() || address instanceof Inet6Address)
continue; //Not interested in loopback or ipv6 this time, thanks
DatagramSocket socket = new DatagramSocket(PORT, address);
//Try to read the broadcast messages from socket here
}
}
もしを初期化するソケットの放送アドレス構築に基づく最初のIPインタフェースの他に、正しいネットマスク:
byte [] mask = { (byte)255, 0, 0, 0 };
byte[] addrBytes = InetAddress.getByName("126.5.6.7").getAddress();
for (int i=0; i < 4; i++) {
addrBytes[i] |= ((byte)0xFF) ^ mask[i];
}
InetAddress bcastAddr = InetAddress.getByAddress(addrBytes);
それだけ投げBindExceptionを構築する場合は、DatagramSocket.
編集: BindException(java.います。BindException:できな割り当て要求アドレス)からの呼び出しDatagramSocketのコンストラクタは、放送アドレス(例:126.255.255.255)のみ付属しております最新のUbuntu9.04(れていないことが考えられUbuntuが、カーネルバージョン固有の問題が)。とUbuntu8.10ことにRed Hatリリース(RHEL4.×さんを対す。
そうでない受信のパケットがバインドされた特定のローカルIPを 正しい行動, が、windowsではこの作品。ただしLinux(RHELおよびUbuntu).低レベルのCコードが回避策setsockopt(SO_BINDTODEVICE)が見つからなるドキュメンテーションシステム-Apiを用意しています。 この なってくれるバーストとの楽観的なもの:-)
解決
このたIPV6Linuxカーネルを発行します。通常、私はIPV6が無効なすべての種類のります。ただし、Ubuntu9.04でハードを無効にするIPV6ったことになるビットだった。
聞放送からのメッセージを一定のインタフェース、まず"放送のバージョン"のインタフェースのIPアドレス:
byte [] mask = { (byte)255, 0, 0, 0 };
byte[] addrBytes = InetAddress.getByName("126.5.6.7").getAddress();
for (int i=0; i < 4; i++) {
addrBytes[i] |= ((byte)0xFF) ^ mask[i];
}
InetAddress bcastAddr = InetAddress.getByAddress(addrBytes);
付与され、これは当てはまりません本当に結合しうる面が多くのインタフェースIPを同じネットワーク部が、私にとってこのソリューションでは十分です。
そのdatagramsocketる住所、ご希望のポートします。ななのは以下のシステムプロパティには、JVM:
-Djava.net.preferIPv6Addresses=false -Djava.net.preferIPv4Stack=true
わたしにはわかりませんどのようIPV6の運休憩を聞放送では、上記のパラメータを修理してください。
他のヒント
だがこれが私の一覧を取得するためのすべてのネットワークインターフェイス:
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
かに結合でき、それに対応していますか?
のつもりでしたが、あの例のgetNetworkInterfaces().
は、私の知る限りにおいてのみ行うことに
IP_RECVDSTADDR
ソケットオプションです。このオプションが付けられることがないよう、dstのアドレスのインタフェースにパケットした上でご利用の場合には、ワイルドカードアドレスです。その作品が放送さすぎます。
こちらはCとえばピックアップしていただき、インターネット:
トを読み込んでアップ recvmsg
そうだこのインタフェースはJava.
編集:
はないが現実のものとなる可能性がある一つのオプションの場合は対応してJava.すする必要があり、 IP_RECVDSTADDR
ソケットオプションのないものの代わりにrecvmsgを使用してくださrawソケットの宛先アドレスからのIPヘッダを表します。
開設ソケットとして使用 SOCK_RAW
まのIPヘッダの初めには、それぞれのメッセージを含むソースと宛先アドレスによりア
以下に例を示しますのUDPを用いて、rawソケットC Linuxの場合:
さんに驚いたこのメソッドが動作しないJavaもございます
Edit2
ります。理由がありま使用できませんマルチキャストまたは特定の理由を選択した放送過マルチキャスト?調査を実施しているのは、同じ理解とマルチキャスト使いたいのインタフェースにパケットを受けるかを常に結合固有のインタフェースに参加の場合はマルチキャストグループを中心に、IP4が結合するインタフェースへの経由の一つでIPアドレス).
できないコメントを、このとして解答する。
それは興味深い。もamんなぜい
byte[] addrBytes = InetAddress.getByName("126.5.6.7").getAddress();
だけではなく
byte[] addrBytes = {126, 5, 6, 7);
それともこのアドレスを取得しい文字列として?