Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使多播套接字可从另一个线程访问_Java_Multithreading_Multicast - Fatal编程技术网

Java 使多播套接字可从另一个线程访问

Java 使多播套接字可从另一个线程访问,java,multithreading,multicast,Java,Multithreading,Multicast,现在我有一个设备向多播组发送UDP消息。我编写了一个小Java程序,可以通过加入组并查找正确的端口来检测这些数据包。我使用MulticastSocket.receivePackage;命令为此,我将继续使用GUI编写一个程序。我希望用户能够指定一个时间量,并让我的程序在这个时间量内查找数据包。我做了大量的研究,发现最好的方法是过早地关闭端口,即在阻塞端口时切断接收命令。为了做到这一点,我让我的程序打开另一个线程,并使用新线程在主线程休眠指定时间的同时监视UDP数据包。它可以很好地检测数据包。但是

现在我有一个设备向多播组发送UDP消息。我编写了一个小Java程序,可以通过加入组并查找正确的端口来检测这些数据包。我使用MulticastSocket.receivePackage;命令为此,我将继续使用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 with的是另一个方法。我的问题是如何使其可供查看?我试了一下这个

public volatile MulticastSocket socket;
main方法可以访问它,但在run方法中无法连接到某个端口。我能找到的唯一可能做这件事就是绑定。但是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{
^
所以我想我真正需要做的是在类级别初始化多播端口,然后将其放入方法内的try块中,正如JTMon所建议的那样。但是我想不出一种方法,在初始化过程中只选择它的端口而不选择它

编辑2: 我仍然有困难。如果我尝试在类级别这样初始化它:

public volatile MulticastSocket socket;

以后如何在run方法中编辑它的端口?

socket2是一个局部变量,因此它的作用域只是定义它的try块。使用MulticastClient_v2实例,您只能访问该类的字段。

socket2是一个局部变量,因此它的作用域只是定义它的try块。使用MulticastClient_v2实例,您只能访问该类的字段。

socket2不是在run方法中声明为局部变量吗?它将无法从该方法之外的任何地方访问。首先尝试在类级别声明它,看看会发生什么。

socket2不是在run方法中声明为局部变量吗?它将无法从该方法之外的任何地方访问。首先尝试在类级别声明它,看看会发生什么。

我将尝试在这里放一些代码来解释我的确切意思。 在类级别声明变量socket2

MulticastClient_v2类应具有以下类型的公共构造函数:

public MulticastClient_v2(int portNumber){
    try{
        socket2 = new MulticastSocket(portNumber);
    }catch(IOException e){
        //Do something with exception here
    }
}
如果端口号没有改变,您可以硬编码,但这种方式更灵活。
在run方法中,您现在可以使用初始化的套接字,并且仍然可以从类外部访问它。尽管我希望您通过线程上的另一个方法进行访问,但这可能是另一个线程的讨论

我将尝试在这里放一些代码来解释我的确切意思。 在类级别声明变量socket2

MulticastClient_v2类应具有以下类型的公共构造函数:

public MulticastClient_v2(int portNumber){
    try{
        socket2 = new MulticastSocket(portNumber);
    }catch(IOException e){
        //Do something with exception here
    }
}
如果端口号没有改变,您可以硬编码,但这种方式更灵活。
在run方法中,您现在可以使用初始化的套接字,并且仍然可以从类外部访问它。尽管我希望您通过线程上的另一个方法进行访问,但这可能是另一个线程的讨论

我以前尝试过在类级别声明它,但它会引发IOException。所以我试着把它放在一个try..throw中,但它说我必须在一个方法中这样做。我以前试过在类级别声明它,但它抛出了一个IOException。所以我试着把它放在一个try..throw中,但它说我必须在一个方法中这样做。所以我试着把它放在一个try..throw中,但它说我必须在一个方法中这样做。将它声明为一个字段并在构造函数中初始化它。在类级别声明变量并在方法内部的try catch中使用它,然后发布IO错误详细信息,我们将再次尝试解决它。。。。。或者其他人会;创建一个构造函数,在构造函数中使用try-catch块并在那里初始化socket2。我还是不明白你为什么需要两个套接字。好吧,我要试试构造函数。我不需要两个插座
s、 在我尝试过在类级别初始化socket之后,我就把它设置成了这样。这是一种让我明白他们的问题是什么的方法。在我所有的尝试中,因为我只是注释掉了声明socket2的行。我以前尝试过在类级别声明它,但它抛出了一个IOException。所以我试着把它放在一个try..throw中,但它说我必须在一个方法中这样做。将它声明为一个字段并在构造函数中初始化它。在类级别声明变量并在方法内部的try catch中使用它,然后发布IO错误详细信息,我们将再次尝试解决它。。。。。或者其他人会;创建一个构造函数,在构造函数中使用try-catch块并在那里初始化socket2。我还是不明白你为什么需要两个套接字。好吧,我要试试构造函数。我不需要两个套接字,我只是在我在类级别尝试初始化套接字之后将其设置为那样。这是一种让我明白他们的问题是什么的方法。在我所有的尝试中,因为我只是注释掉声明socket2的行。