現在、UDP メッセージをマルチキャスト グループに送信するデバイスがあります。グループに参加して適切なポートを探すことで、これらのパケットを検出できる小さな Java プログラムを作成しました。私はMulticastSocket.receive(packet);
指図。この目的のために、GUI を使用したプログラムの作成に進みます。ユーザーが時間を指定できるようにし、プログラムがこの時間のパケットを検索できるようにしたいと考えています。多くの調査を行った結果、ポートをブロックしているときに受信コマンドを切断する最善の方法は、ポートを時期尚早に閉じることであることがわかりました。これを行うには、プログラムで別のスレッドを開き、新しいスレッドを使用して、メイン スレッドが指定された時間スリープしている間に UDP パケットを監視します。パケットを問題なく検出しています。ただし、メインスレッドからアクセスしてポートを閉じることはできないようです。これが私のコードです:
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
public class MulticastClient_v2 extends Thread
{
public volatile MulticastSocket socket;
public void run()
{
try {
//Declare the port and IGMP Group IP
MulticastSocket socket2 = new MulticastSocket(5000);
InetAddress address = InetAddress.getByName("224.0.1.2");
//Display connection information
System.out.println("Joining 224.0.1.2 on port 5000");
//Join the Multicast Group
socket.joinGroup(address);
//Declaring a DatagramPacket
DatagramPacket packet;
//Starting an infinite loop
//while (true)
//{
System.out.println("Waiting on packets..");
byte[] buf = new byte[1024];
packet = new DatagramPacket(buf, buf.length); //Declaring an internal DatagramPacket
socket.receive(packet); //Receiving a Packet
String received = new String(packet.getData(), 0, packet.getLength());
InetAddress senderAddress = packet.getAddress(); //Get the InetAddress object
String forFun = senderAddress.getHostAddress(); //Extract the IP address of sender in text format
if (received.indexOf("Product1") >= 0) //Searching the raw data for "Product1"
{
//If found, display the IP and device type
System.out.println("Product1 found at " + senderAddress);
}
if (received.indexOf("Product2") >= 0) //Searching the raw data for "Product2"
{
//If found, display the IP and device type
System.out.println("Product2 found at " + senderAddress);
}
//}
}
catch(IOException ex)
{
System.out.println (ex.toString());
}
}
public static void main(String[] args)
{
MulticastClient_v2 thread = new MulticastClient_v2();
thread.start();
try {
Thread.sleep( 3000 );
thread.socket2.close();
}
catch(InterruptedException in)
{
System.out.println("Interrupted Exception!");
}
System.out.println("Done.");
}
}
そのため、コンパイルしようとすると、次のエラーが発生します。
MulticastClient_v2.java:63: error: cannot find symbol
thread.socket2.close();
^
symbol: variable socket2
メインメソッドがsocket2を見ることができず、別のメソッドにあるように思えます。私の質問は、それを表示できるようにする方法です。私は少し実験しました
public volatile MulticastSocket socket;
メインメソッドはそれにアクセスできますが、実行メソッドにいるときに特定のポートに接続できません。これを行うことができる唯一のものは bind() です。ただし、bind() には IP とポートの両方が必要ですが、最初にマルチキャスト ソケットを宣言するときは、次のようにポートだけを宣言できます。
MulticastSocket socket2 = new MulticastSocket(5000);
どんな助けでも大歓迎です!私はこれでしばらく立ち往生しています。
編集:私はいくつかの提案を得ました。まず、クラス レベルで宣言して初期化する必要があります。これにより、次の IO エラーが発生します。
MulticastClient_v2.java:8: error: unreported exception IOException; must be caught
or declared to be thrown
public volatile MulticastSocket socket = new MulticastSocket(5000);
^
次に、クラス レベルで try..catch ブロックに入れてみたところ、次のようになりました。
MulticastClient_v2.java:8: error: illegal start of type
try{
^
したがって、JTMon が提案したように、クラス レベルでマルチキャスト ポートを初期化し、それをメソッド内の try ブロックに配置する必要があると思います。しかし、初期化中にそれを行わずにポートだけを選択する方法がわかりません。
編集 2: まだ問題があります。クラスレベルでそのように初期化しようとすると:
public volatile MulticastSocket socket;
後で run() メソッドでそのポートを編集するにはどうすればよいですか?