简体   繁体   English

服务器未收到客户端的消息

[英]The server is not receiving the message of the client

I'm new to Java socket programming and I'm trying to write a program which is supposed to be run on 2 separate controllers. 我是Java套接字编程的新手,正在尝试编写一个应在2个单独的控制器上运行的程序。 I have written a thread which is used as the communication class. 我编写了一个用作通信类的线程。

I have defined a flag called SFlag so that when the value of this flag is changed to 1 anywhere in my program, the corresponding controller will send a hello message to the other controller through sendPackets() function. 我定义了一个名为SFlag的标志,以便在程序中的任何位置将此标志的值更改为1时,相应的控制器都会通过sendPackets()函数向另一个控制器发送问候消息。 The other controller will receive this message through ReceivePackets class and it will print the result. 另一个控制器将通过ReceivePackets类接收此消息,并将打印结果。 Here is the code: 这是代码:

// My UDP communication class
    public class MainConn implements Runnable {

        // Sockets, 1 for sending, and one for receiving
        DatagramSocket socket1, socket2;

        // localIP
        private InetAddress localIP;
        private InetAddress leaderIP;

        // classes to run on separate Threads
        private ReceivePackets rcvThread;


        @Override
        public void run() {
            process();
        }

        public void process() {

            // initialize some parameters
            init1();

            // Make Thread for receiving packets and update counters from all
            // controller
            rcvThread = new ReceivePackets();
            Thread r = new Thread(rcvThread);
            r.start();

            sendPackets();
        }

        public void init1() {
            try {
                // create sockets
                String tempString = config.get("localPort");
                localPort = Integer.parseInt(tempString);
                logger.info("----------here is==========" +localPort);

                leaderIP = InetAddress.getByName("127.0.0.1");
                logger.info("----------here is==========" +leaderIP);

                socket1 = new DatagramSocket(localPort); // for sending
                socket2 = new DatagramSocket(localPort + 1); // for receiving
            } catch (SocketException | UnknownHostException e) {
                e.printStackTrace();
            }
        }


        //*******************************************************

        public void sendPackets() {
            // will be used to begin sending message type II after 3*hello
            // period

            while (true) {
                try {

                    // if network not converged, send message type I, contains:
                    // type number (1) then
                    if (SFlag == 1) {               
                        logger.info("Sending the message");
                        String tempString = new String("Hello");

                        byte[] data = tempString.getBytes();                
                        DatagramPacket sentPacket = new DatagramPacket(data, tempString.length());
                        sentPacket.setAddress(leaderIP);
                        sentPacket.setPort(20222);
                        socket1.send(sentPacket);
                        SFlag = 0;
                    }
                    else {
                        logger.info("Nothinggggggggggggg");
                    }

                    Thread.sleep(5000);// wait for Hello period

                } catch (SocketException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                catch(Exception e){
                    e.printStackTrace();
                }

            }
        }

        class ReceivePackets implements Runnable {

            @Override
            public void run() {
                try {
                    while (true) {
                        logger.info("---------------waiting------------------");
                        byte[] data = new byte[1000];
                        DatagramPacket receivedPacket = new DatagramPacket(data, data.length);
                        socket2.receive(receivedPacket);
                        String senderIP = receivedPacket.getAddress().getHostAddress();
                        String senderPort = "" + receivedPacket.getPort();
                        String message = new String(data, 0, receivedPacket.getLength());
                        logger.info(message);

                        System.out.println("Received Message: "+message);
                        }

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }
    }

When the value of SFlag is changed to 1, it seems that the first controller is sending the message ("Sending the message" is printed), but there seems to be a problem with receiving the message on the second controller, because the received message is not printed. 当SFlag的值更改为1时,似乎第一个控制器正在发送消息(已打印“正在发送消息”),但是在第二个控制器上接收消息似乎存在问题,因为已接收到消息不打印。

What is the problem? 问题是什么?

There are some issues with your code: 您的代码存在一些问题:

(1) Since both threads rely on SFlag for communication, make sure it is declared with the volatile keyword: (1)由于两个线程都依赖SFlag进行通信,因此请确保使用volatile关键字声明它:

private volatile int SFlag = 0;

The volatile keyword prevents the variable from being cached, so both threads will see the same value all the time. volatile关键字可防止对该变量进行缓存,因此两个线程始终会看到相同的值。 Besides that, reading and writing operations on volatile variables are atomic. 除此之外,对volatile变量的读写操作是原子的。

(2) You have a hardcoded port number in this line: (2)您在此行中有一个硬编码的端口号:

sentPacket.setPort(20222);

Make sure this is the port number used by the ReceivePackets thread. 确保这是ReceivePackets线程使用的端口号。 Ideally we should never have magic numbers mixed with the code. 理想情况下,我们永远不要将魔术数字与代码混在一起。 So you should move that port number to a separate variable or constant. 因此,您应该将该端口号移至单独的变量或常量。

(3) In Java you shouldn't create a String with new . (3)在Java中,您不应该使用new创建一个String For example, this is bad practice: 例如,这是一种不好的做法:

String tempString = new String("Hello"); // bad practice

You should do: 你应该做:

String tempString = "Hello";

My last piece of advice is: clean up your code . 我的最后一条建议是:清理代码 You can look at Oracle's tutorial on sending and receiving datagram packets here: https://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html 您可以在此处查看有关发送和接收数据报包的Oracle教程: https : //docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM