0

Привет, Я посылаю трансляцию с использованием DatagramSocket с определенным номером порта. Его сообщение успешно отправлено. Но когда я слушаю сообщение приема с открытым ip-адресом и любым номером порта, он бросает вызов sockettimeoutexception. Но я связан с одной и той же сетью.Прослушивание сокета datagram с любым ip и любым номером порта android

// манифеста

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

// определяется номер порта глобально

int PORT=2739; 

// начиная ASync задачу

new MyClientTask().execute(); 

/// асинхронной задача

public class MyClientTask extends AsyncTask<Void, Void, Void> { 

     @Override 
     protected Void doInBackground(Void... arg0) { 

      new PacketSender().run(); 
      new PacketReceiver().run(); 

      return null; 
     } 

     @Override 
     protected void onPostExecute(Void result) { 
      super.onPostExecute(result); 


     } 

    } 

Это моя отправка запроса

public class PacketSender implements Runnable { 
     @Override 
     public void run() { 
      DatagramSocket sendSoc = null; 
      try { 
       sendSoc = new DatagramSocket(); 
       sendSoc.setBroadcast(true); 
       sendSoc.setSoTimeout(5000); 
       sendSoc.setReuseAddress(true); 
       byte[] ip = prop.ToBuffer(); 
       DatagramPacket packet = new DatagramPacket(ip, 
         ip.length, getBroadcastIp(), PORT); 
       Log.d("Sending", packet.getAddress().getHostAddress() + " " + packet.getPort()); 
       sendSoc.send(packet); 
       sendSoc.close(); 
      } catch (IOException e) { 
       Log.d("Send", "IOException"); 
       e.printStackTrace(); 
       if (sendSoc != null) 
        sendSoc.close(); 
      } 
     } 
    } 

Это мой запрос прослушивания

public class PacketReceiver implements Runnable { 
     @Override 
     public void run() { 
      DatagramSocket receiveSoc = null; 
      try { 
       //here 0 represent any port number including system reserved port number 
       receiveSoc = new DatagramSocket(0, InetAddress.getByName("0.0.0.0")); 
       receiveSoc.setBroadcast(false); //also tried with true 
       receiveSoc.setSoTimeout(5000); //alse tried with removing timeout value 

       int i = 0; 
       while (true) { 
        Log.d("data value", " " + i); 
        i++; 
        byte buf[] = new byte[1024]; 
        DatagramPacket pack = new DatagramPacket(buf, buf.length); 

        try { 
         receiveSoc.receive(pack); 

         String message = new String(pack.getData()).trim(); 
         Log.i("test", message + " server ip : " + pack.getAddress().getHostAddress()); 

        } catch (UnknownHostException e) { 
         e.printStackTrace(); 
        } 
       } 
      } catch (SocketTimeoutException e) { 
       Log.d("Main", "SocketTimeoutException"); 
       e.printStackTrace(); 
       receiveSoc.close(); 
       new PacketReceiver().run(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       Log.d("Response", "IOException"); 
       e.printStackTrace(); 
      } 
     } 
    } 

// получение широковещательного IP

public InetAddress getBroadcastIp() throws IOException { 
     DhcpInfo dhcp = myWifiManager.getDhcpInfo(); 
     int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask; 
     byte[] quads = new byte[4]; 
     for (int k = 0; k < 4; k++) 
      quads[k] = (byte) ((broadcast >> k * 8) & 0xFF); 
     return InetAddress.getByAddress(quads); 
    } 

Он может иметь возможность получать широковещательное сообщение от все хоста в LAN, кроме аппаратного обеспечения, с которым я хочу общаться. Я могу отправить трансляцию этому. Но я не могу получать трансляцию с этого устройства.

+0

Прокомментируйте, пожалуйста, если вы не поняли. – Nas

ответ

0

Я установил этот вопрос с ниже. Нет проблем с пересылкой пакетов в сети. Я отправляю и получаю трансляцию на одном и том же объекте сокета с значением setBroadcast true. Таким образом, сокет отправляет широковещательную рассылку и прослушивает любую трансляцию из нее. Вы не должны использовать другой объект сокета для прослушивания широковещательной передачи. Я понимаю это очень поздно.

public class PacketSender extends Thread { 
     @Override 
     public void run() { 
      DatagramSocket sendSoc = null; 
      try { 
       sendSoc = new DatagramSocket(); 
       sendSoc.setBroadcast(true); 
       InetSocketAddress address = new InetSocketAddress(getBroadcastQuadIp(), PORT); 

       byte[] ip = prop.ToBuffer(); 
       DatagramPacket packet = new DatagramPacket(ip, 
         ip.length, address.getAddress(), address.getPort()); 


       sendSoc.send(packet);  

       //////////// receiver begin 
       int i = 0; 
       while (true) { 

        i++; 

        final byte buf[] = new byte[1024]; 
        final DatagramPacket pack = new DatagramPacket(buf, buf.length); 
        try { 
         sendSoc.receive(pack); 

         String message = new String(pack.getData()).trim(); 

         Log.i("test", message + " server ip : " + pack.getAddress().getHostAddress()); 

        } catch (UnknownHostException e) { 
         e.printStackTrace(); 

        } 
       } 
      } catch (IOException e) { 
       Log.d("Send", "IOException"); 
       e.printStackTrace(); 
       if (sendSoc != null) 
        sendSoc.close(); 
      } 
     } 
    } 
0

сделать эти изменения в код:

public class PacketSender implements Runnable { 

    @Override 
    public void run() { 

     // ... 

     DatagramPacket packet = new DatagramPacket(ip, 
       ip.length, InetAddress.getByName("255.255.255.255"), PORT); 

     // ... 
    } 
} 
public class PacketReceiver implements Runnable { 

    @Override 
    public void run() { 

     // ... 

     receiveSoc = new DatagramSocket(PORT, InetAddress.getByName("0.0.0.0")); 

     // ... 
    } 
} 

UPDATE

MyClientTask код не работает, потому что он называет отправителя и последовательно приемника. Отправитель не отправит никому, и получатель будет ждать вечно без сообщения. Вы должны позвонить отправителю, пока приемник уже прослушивает датаграммы.

Таким образом, вместо

new MyClientTask().execute(); 

Вы хотите что-то вроде

new Thread(new PacketReceiver()).start(); 

// Just to make sure that the receiver has started up. 
// You'll want to do a different kind of synchronization. 
SystemClock.sleep(50); 

new Thread(new PacketSender()).start(); 
+0

благодарим вас за ответ. Это не работает . Даже его не отправка сообщений. Прежде, чем это было хорошо. – Nas

+0

@ Не выставлять код, который вызывает эти runnables – nandsito

+0

@ Не добавляли ли вы к манифесту использование-разрешающий интернет? – nandsito

Смежные вопросы