java - Multicastsocket 在无限循环中不断接收相同的消息

标签 java network-programming multicast java-threads

我正在使用多播编写一个java聊天应用程序。 客户端可以在它们之间进行通信,但它们也可以向服务器发送预定义的消息,服务器始终对相应的预定义消息有相同的答案。

客户端和服务器端都可以接收和发送消息。它们都向相同的主机和端口订阅接收者,因此它们的套接字是相同的,但是当客户端向服务器发送预定义消息时,服务器会陷入接收相同消息的无限循环中。

代码服务器

       final Lock lock = new ReentrantLock();
       final Condition Rx  = lock.newCondition(); 
       final Condition Tx = lock.newCondition(); 
       private volatile boolean msgRead;
       private volatile int TypeMsg;

       try{
            NetworkInterface nif = NetworkInterface.getByName("en1");
            MSocket = new MulticastSocket(port_chat);
            group = InetAddress.getByName(adresse_chat);
            MSocket.joinGroup(new InetSocketAddress(adresse_chat, port_chat), nif);
        }catch(IOException se){
            System.out.println(this.toString() + " IOException -> " + se.getMessage());
        }

       /*
            Thread Rx
        */

        new Thread(){
            @Override
            public void run(){
                while(!isInterrupted()){
                    lock.lock();
                    try{
                        while(msgRead == true)
                            Rx.await();
                        byte[] buf = new byte[256];
                        DatagramPacket packetRx = new DatagramPacket(buf, buf.length);
                        try{
                            MSocket.receive(packetRx);
                        }catch(IOException ioe){
                            System.out.println(this.toString() + " IOException -> " + ioe.getMessage());
                        }

                        String received = new String(packetRx.getData(), 0, packetRx.getLength());
                        if("end".equals(received))
                            break;

                        if(received.contains("WEATHER_FORECAST") == true)
                            TypeMsg = 1;
                        else
                            if(received.contains("ASK_AGE_CAPTAIN") == true)
                                TypeMsg = 2;

                        msgRead = true;
                        Tx.signal();
                    }catch(InterruptedException ie){
                        System.out.println("Thread Rx -> " + ie.getMessage());
                    }
                    finally{
                        lock.unlock();
                    }
                }
            }
        }.start();

        /*
            Thread Tx
        */

        new Thread(){
            @Override
            public void run(){
                while(!isInterrupted()){
                    lock.lock();
                    try{
                        while(msgRead == false)
                            Tx.await();

                        byte[] buf = new byte[256];

                        /* switch(TypeMsg){...} */

                        buf = text.getBytes();
                        DatagramPacket packetTx = new DatagramPacket(buf, buf.length, group, port_chat);

                        try{
                            MSocket.send(packetTx);
                        }catch(IOException ioe){
                            System.out.println(this.toString() + " IOException -> " + ioe.getMessage());
                        }
                        msgRead = false;
                        Rx.signal();
                    }catch(InterruptedException ie){
                        System.out.println("Thread Tx -> " + ie.getMessage());
                    }finally{
                        lock.unlock();
                    }
                }
            }
        }.start();

代码客户端

     try{
            NetworkInterface nif = NetworkInterface.getByName("en1");
            MSocket = new MulticastSocket(port_chat);
            group = InetAddress.getByName(adresse_chat);
            MSocket.joinGroup(new InetSocketAddress(adresse_chat, port_chat), nif);
        }catch(IOException se){
            System.out.println(this.toString() + " IOException -> " + se.getMessage());
        }

/*  
    Thread Rx
*/
new Thread(){
            @Override
            public void run(){
                while(!isInterrupted()){
                    byte[] buf = new byte[256];
                    DatagramPacket packetRx = new DatagramPacket(buf, buf.length);
                    try{
                        MSocket.receive(packetRx);
                    }catch(IOException ioe){
                        System.out.println(this.toString() + " IOException -> " + ioe.getMessage());
                    }

                    String received = new String(packetRx.getData(), 0, packetRx.getLength());
                    if("end".equals(received))
                        break;

                    jTextArea_Rx.append(received + "\n");
                }
            }
        }.start();

/*
  Tx
*/
private void jButton_SendActionPerformed(java.awt.event.ActionEvent evt) {                                             
        byte[] buf = new byte[256];
        String text = username + " >> " + jTextArea_Tx.getText();
        buf = text.getBytes();

        DatagramPacket packetTx = new DatagramPacket(buf, buf.length, group, port_chat);

        try{
            MSocket.send(packetTx);
        }catch(IOException ioe){
            System.out.println(this.toString() + " IOException -> " + ioe.getMessage());
        }
    }

最佳答案

这感觉好像与IP_MULTICAT_LOOP套接字选项有关,这令人惊讶enabled by default in Java Multicast Sockets 。基本上,当启用此标志时,您将收到在多播套接字上发送的消息。因此,如果您在收到消息时也发送消息并且启用了此功能,则可以创建循环。

尝试禁用此套接字选项,看看会发生什么。

关于java - Multicastsocket 在无限循环中不断接收相同的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59494538/

相关文章:

java - 如何强制 Eclipse Applet Viewer 执行安全检查?

c# - ThreadPool 和带有 while(true) 循环的方法?

Java多线程服务器解释请

java - Linux 上 Java 和 Zeroconf (avahi) 的多播问题

docker - docker用户定义的桥接网络是否支持多播?

java - 在java中计算字符串中的空格

java zip 存档损坏

java - 定义我的所有 gradle 项目都可以看到的属性集

c - "Connected"UDP套接字,双向通信?

go - 组播环回