2016-10-07 7 views
0

서버로 작동하는 일부 내장형 장치와 통신하기 위해 안드로이드 소스 (단지 java)를 작성하고 있습니다.Java UDP 소켓은 바이트를 반향합니다.

가 나는 장치 상태 변화를 관찰 할 수 있기 때문에 내 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++로 작성된)를 쓴 사람은 그가 자신의 테스트 케이스의 응답을 받고 있다고, 그래서 나는 무엇을 누락 될 수 있습니다? 위 코드가 서버의 데이터 그램을 무시하고 내 코드에서 보낸 에코 바이트를 무시할 가능성이 있습니까?

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

답변에 따라 코드를 변경했습니다. 나는 더 이상 청취 스레드를 사용하지 않습니다. 여기 내 코드가있다.

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(); 
} 

하트 비트 바이트에 따르면 내가 받고있어 (그것을! "HEARTBEAT"만들 것이다 문자열로 제작), 송신자는 192.168.5.1입니다. 하지만 여전히 하트 비트 만받습니다. 나는 무엇을 놓치겠습니까?

답변

1
  • (192.168.5.255로) 브로드 캐스트 중이기 때문에 자신의 데이터 그램을 수신하고 있습니다. 장치의 실제 IP 주소를 사용해야합니다.
  • 송신마다 새 데이터 그램 소켓을 생성하지 마십시오. (당신은 결코 소켓을 닫는 없다, 그래서 당신은 또한 소켓을 누출하고 있습니다.)
  • 당신은 당신이 받고있는 동일한 소켓에서 데이터 그램을 보내야합니다. 장치는 요청이 보낸 IP : 포트에 응답해야하며 (현재) 매회마다 다르며 해당 포트에 바인딩 된 송신 소켓을 잃어 버리고 있으며 보내는 IP : 포트는 IP가 아닙니다. : 당신이 듣고있는 항구, 그래서 당신은 그것을 듣지 않습니다.
  • 청취 소켓을 특정 IP 주소에 바인딩하면 안되며 브로드 캐스트 주소에는 바인딩하지 않아야합니다. 나는 그것이 효과가있어 놀랍다.
+0

데이터 그램을 특정 주소와 포트로 보내지 않습니까? 장치는 항상 동일한 네트워크 내에 있음을 보장합니다. '기기의 실제 IP 주소'란 무엇입니까? – March3April4

+0

브로드 캐스트 주소 인 192.168.5.255로 보냅니다. '장치의 실제 IP 주소'는 더 이상의 설명이 필요하지 않습니다. – EJP

+0

왜 이런 일이 일어 났는지 궁금하지 않습니다. 나는 심지어 255가 방송 주소라는 것을 몰랐다. 고맙습니다. 한 번만 더 질문합니다.방송을 수신 할 때 실제 발신자의 IP에서 알 수 있습니까? 장치는 5 초마다 하트 비트 바이트를 보냅니다. – March3April4

0

EJP가 말한 것은 모든 것에 대해 옳았습니다.

그 (것)들에서 끝을 포함한 위의 고정 코드 (가장 아래 코드 스 니펫)는 혼자 방송을받을 필요없이 작동 할 것입니다.

아직 장치에서 응답을받지 못 했으므로 문제가 해결되지 않았다고 생각했지만 고장난 장치였습니다. 위의 코드는 잘 작동합니다.