Java UDP套接字回显字节

时间:2016-10-07 00:11:08

标签: java android udp datagram

我正在编写一个android源码(但只是java)与一些充当服务器的嵌入式设备进行通信。

我确信我的UDP数据报到达设备,因为我可以观察设备状态的变化。

但问题是我无法从服务器获得响应。什么都没有收到,但我只是回应了我发送的内容。我的来源如下。

 public void sendSnapShot(View view) {
 //send a udp datagram to the server.
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... voids) {

            try {
                Log.e("Test", "send sendSnapShot onLine");

                DatagramSocket clientSocket = new DatagramSocket();

                byte[] sendData = new byte[1024];

                String sentence = "$SNAPSHOT";

                sendData = sentence.getBytes();


                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("192.168.5.255"), 9999);
                clientSocket.send(sendPacket);

                Log.e("Test", "Sent sendSnapShot REQUEST");

            } catch (Exception e) {
                Log.e("Test", "e", e);
            }

            return null;
        }
    }.execute();
}

上面的代码是关于将数据报传输到服务器的。在应用程序启动时,将启动以下线程以侦听服务器发送的任何数据报。

 private class ListenerThread implements Runnable {
    //listen for incoming datagrams.
       @Override
       public void run() {
           DatagramSocket serverSocket = null;
           try {
            InetAddress serverAddr = InetAddress.getByName("192.168.5.255");
            serverSocket = new DatagramSocket(9999, serverAddr);

            while (true) {
                try {

                    byte[] receiveData = new byte[1024];

                    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                    serverSocket.receive(receivePacket);
                    receivePacket.getLength();
                    String receivedData = new String(receivePacket.getData(), 0, receivePacket.getLength());
                    if (!receivedData.startsWith("!HEARTBEAT")) {
                        Log.e("Test", "Received : " + receivedData);
                    } else {
                        Log.e("Test", "Received : HEARTBEAT");
                    }
                } catch (Exception e) {
                    Log.e("Test", "FROM SERVER ", e);

                }
            }
 } catch (Exception e) {
            Log.e("Test", "Exception", e);
            }
        }
    }

编写服务器代码的人(可能是用c ++编写的)说他在测试用例中得到了回应,所以我可能会缺少什么?是否有可能上述代码将忽略来自服务器的任何数据报和从我的代码发送的echo字节?

=============================================== ==============================

我已根据答案更改了我的代码。我不再使用监听线程了。这是我的代码。

public void sendBattery(View view) {
        new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... voids) {

            try {
                Log.e("Test", "send Battery onLine");

                DatagramSocket clientSocket = new DatagramSocket(9999, InetAddress.getByName("0.0.0.0"));

                byte[] sendData = new byte[1024];
                byte[] receivedata = new byte[1024];

                String sentence = "$S0B255";
                DatagramPacket receivePacket = new DatagramPacket(receivedata, receivedata.length);

                sendData = sentence.getBytes();
                String receivedData = " ";
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("192.168.5.1"), 9999);
                clientSocket.send(sendPacket);
                do{
                    clientSocket.receive(receivePacket);
                    receivedData = new String(receivePacket.getData(), 0, receivePacket.getLength());
                    Log.e("Test", receivedData +  ", IP CHECK Sender:  : " + receivePacket.getAddress().toString() + ", port : "+ receivePacket.getPort());
                }while(true);
               // Log.e("Test", "Sent BATTERY REQUEST COMPL");
            } catch (Exception e) {
                Log.e("Test", "e", e);
            }

            return null;
        }
    }.execute();
}

根据心跳字节(将其设为字符串将使其成为&#34;!HEARTBEAT&#34;)我收到,发件人为192.168.5.1。但是,我只能获得心跳字节。我该失踪什么?

2 个答案:

答案 0 :(得分:1)

  • 您正在接收自己的数据报,因为您正在广播(至192.168.5.255)。您应该使用设备的实际IP地址。
  • 您不应该为每个发送创建一个新的数据报套接字。 (你永远不会关闭那个套接字,所以你也在泄漏套接字。)
  • 您应该从您接收的同一个套接字发送数据报。设备将(应该)回复请求来自的IP:端口,并且目前每次都不同,并且您丢失了绑定到该端口的发送套接字,并且发送IP:端口不是您正在收听的IP:端口,因此您无法听到。
  • 您不应将侦听套接字绑定到特定的IP地址,当然也不应绑定到广播地址。我很惊讶它有效。

答案 1 :(得分:0)

EJP所说的一切都是正确的。

上面的固定代码(最下面的代码片段)包含了他的提示,无需我自己接收任何广播。

我认为这个问题没有得到解决,因为我仍然没有从设备那里得到任何回复,但这是设备(不是由我制造)发生故障。上面的代码会很好用。