2013-03-20 12 views
14

Sto guardando la possibilità di trasmettere tramite una connessione Wi-Fi Direct tra più dispositivi Android. Ho creato un'applicazione di trasmissione di messaggi semplice per verificare se funziona o meno, ma finora non sono stato in grado di trasmettere un messaggio. Quando cerco di inviare il pacchetto ottengo un SocketException (Network è irraggiungibile):Broadcasting over Wi-Fi Direct

03-20 13:23:00.148: E/UdpBroadcaster(4180): sendto failed: ENETUNREACH (Network is unreachable) 
03-20 13:23:00.148: E/UdpBroadcaster(4180): java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:496) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at libcore.io.IoBridge.sendto(IoBridge.java:465) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at java.net.DatagramSocket.send(DatagramSocket.java:307) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at com.example.android.wifidirect.UdpBroadcaster.sendMessage(UdpBroadcaster.java:59) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at com.example.android.wifidirect.UdpBroadcaster.run(UdpBroadcaster.java:44) 
03-20 13:23:00.148: E/UdpBroadcaster(4180): Caused by: libcore.io.ErrnoException: sendto failed: ENETUNREACH (Network is unreachable) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at libcore.io.Posix.sendtoBytes(Native Method) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at libcore.io.Posix.sendto(Posix.java:146) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  at libcore.io.IoBridge.sendto(IoBridge.java:463) 
03-20 13:23:00.148: E/UdpBroadcaster(4180):  ... 4 more 

questa è l'essenza del mio codice:

InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255"); 
int port = 8888; 

DatagramSocket socket = new DatagramSocket(port); 
socket.setBroadcast(true); 
socket.connect(broadcastAddress, port); 

String message = "Hello"; 
byte[] buffer = message.getBytes(); 

DatagramPacket packet = new DatagramPacket(
     buffer, buffer.length, broadcastAddress, port); 

try { 
    socket.send(packet); // <----- Causes a SocketException 
} catch (IOException e) { 
    Log.e(TAG, e.getMessage(), e); 
} 

This post suggerisce che la trasmissione tramite Wi-Fi Direct dovrebbe essere possibile

Qualcuno sa se la trasmissione via Wi-Fi Direct su dispositivi Android funziona effettivamente? Se dovrebbe funzionare, cosa sto sbagliando?

Sto iniziando a pensare che i dispositivi non sappiano dove instradare i pacchetti di trasmissione. Nel mio caso ha bisogno di lavorare senza dover eseguire il root del dispositivo e aggiungere manualmente una route per i pacchetti broadcast.


Aggiornamento

Dopo aver utilizzato la funzione di getBroadcastAddress() suggerito da Romain Hippeau il SocketException scomparso e sembra che la trasmissione sta funzionando come previsto. Tuttavia, ho problemi a ricevere la trasmissione sul secondo dispositivo.

Sto utilizzando il seguente codice per ricevere la trasmissione:

DatagramSocket socket = null; 
try { 
    socket = new DatagramSocket(8888); 
    socket.setBroadcast(true); // Not needed? 
    socket.setSoTimeout(200); 

    DatagramPacket packet = null; 
    while (!mStopping) { 
     byte[] buffer = new byte[1024]; 
     packet = new DatagramPacket(buffer, buffer.length); 

     try { 
      socket.receive(packet); 

      if (packet.getData().length > 0) { 
       String receivedString = new String(packet.getData()); 

       Log.i(TAG, "Received string: " + receivedString); 
      } 
     } catch (InterruptedIOException e) { /* Ignore */ } 
    } 
} catch (IOException e) { 
    Log.e(TAG, e.getMessage(), e); 
} finally { 
    if (socket != null) 
     socket.close(); 
} 

Ho anche provato ad aggiungere un indirizzo jolly al DatagramSocket aggiungendo InetAddress.getByName("0.0.0.0") come argomento, ma senza fortuna.

Suggerimenti?

+0

BTW: Guardate questo articolo: http: //developer.android.com/training/connect-devices-wirelessly/wifi-direct.html –

risposta

12

spudoratamente rubato da https://code.google.com/p/boxeeremote/wiki/AndroidUDP

provare a ottenere al collegamento di rete in questo modo:

InetAddress getBroadcastAddress() throws IOException { 
    WifiManager wifi = mContext.getSystemService(Context.WIFI_SERVICE); 
    DhcpInfo dhcp = wifi.getDhcpInfo(); 
    // handle null somehow 

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

Quindi provare l'invio di un pacchetto in questo modo:

DatagramSocket socket = new DatagramSocket(PORT); 
socket.setBroadcast(true); 
DatagramPacket packet = new DatagramPacket(data.getBytes(), data.length(), 
    getBroadcastAddress(), PORT); 
socket.send(packet); 

// If you want to listen for a response ... 
byte[] buf = new byte[1024]; 
DatagramPacket packet = new DatagramPacket(buf, buf.length); 
socket.receive(packet); 

Edit: Dal stessa pagina per leggi prova questo ...

WifiManager wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); 
MulticastLock lock = wifi.createMulticastLock("dk.aboaya.pingpong"); 
lock.acquire(); 
serverSocket = new DatagramSocket(19876); 
serverSocket.setSoTimeout(15000); //15 sec wait for the client to connect 
byte[] data = new byte[UDPBatPositionUpdater.secretWord.length()]; 
DatagramPacket packet = new DatagramPacket(data, data.length); 
serverSocket.receive(packet); 
lock.release(); 
String s = new String(packet.getData()); 
System.out.println(s); 

Ricordate, che è necessario il seguente autorizzazione per farlo funzionare:
< usa-autorizzazione android: name = "android.permission.CHANGE_WIFI_MULTICAST_STATE"/>

+3

The SocketException è scomparso dopo aver usato quella funzione per ottenere l'indirizzo di broadcast e la trasmissione sembra funzionare, ma ho problemi a ricevere la trasmissione sul secondo dispositivo.Inizializzo un 'DatagramSocket' nello stesso modo sul dispositivo di ricezione. Ho anche provato ad usare un indirizzo jolly sul 'DatagramSocket' ricevente aggiungendo' InetAddress.getByName ("0.0.0.0") 'come argomento. Senza fortuna. – KatoStoelen

+0

@ user2190832 ha aggiunto ulteriori dettagli alla mia risposta per leggere UDP. –

+0

Il codice funziona benissimo, grazie! Alcuni dettagli sui dispositivi: Costruisco le mie librerie per gestire questa comunicazione basata su questo codice. Attualmente sto usando la porta 8888. Il mio Nexus 5 può inviare e ricevere. Il mio Moto G può solo inviare pacchetti (e ricevere i propri, ma non formare altri dispositivi). Recentemente ho provato un Samsung Galaxy S2 e posso inviare e ricevere pacchetti. In qualche modo Motorola sta bloccando le trasmissioni in arrivo. Ho provato in due Moto G diversi, uno marcito con politiche specifiche del firewall e un titolo, ma senza fortuna. –