2013-03-20 10 views
14

Rozglądam się za możliwością nadawania za pośrednictwem połączenia Wi-Fi Direct między wieloma urządzeniami z Androidem. Stworzyłem prostą aplikację do wysyłania wiadomości, aby sprawdzić, czy działa, ale jak dotąd nie udało mi się nadać komunikatu. Gdy próbuję wysłać pakiet dostaję SocketException (Network jest nieosiągalny):Rozsyłanie za pośrednictwem 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 

To jest istota mojego kodu:

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 sugeruje, że transmisja przez sieć Wi-Fi Direct powinno być możliwe.

Czy ktoś wie, czy urządzenia do transmisji przez Wi-Fi Direct na urządzeniach Android rzeczywiście działają? Jeśli to powinno zadziałać, co robię źle?

Zaczynam myśleć, że urządzenia nie wiedzą, gdzie kierować pakiety emisji. W moim przypadku musi działać bez konieczności rootowania urządzenia i ręcznego dodawania trasy dla pakietów emisji.


Aktualizacja

Po użyciu funkcji getBroadcastAddress() sugerowanego przez Romain Hippeau SocketException zniknął i wydaje się, że transmisja działa zgodnie z przeznaczeniem. Mam jednak problem z odbieraniem transmisji na drugim urządzeniu.

Używam następujący kod do odbioru transmisji:

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

Próbowałem również dodać wieloznaczny adres do DatagramSocket dodając InetAddress.getByName("0.0.0.0") jako argumentu, ale bez powodzenia.

Sugestie?

+0

BTW: Spójrz na tego artykułu: http: //developer.android.com/training/connect-devices-wirelessly/wifi-direct.html –

Odpowiedz

12

Bezwstydnie skradzione https://code.google.com/p/boxeeremote/wiki/AndroidUDP

Spróbuj pozyskiwaniu Połączenie sieciowe w ten sposób:

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

Następnie spróbuj wysłanie pakietu w ten sposób:

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: Z tej samej strony do przeczytaj spróbuj ...

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

Pamiętaj, że musisz następujące zgodę na to, aby pracować:
< wykorzystuje-pozwolenie android: name = "android.permission.CHANGE_WIFI_MULTICAST_STATE"/>

+3

Wyjątek SocketException zniknął po użyciu tej funkcji, aby uzyskać adres rozgłoszeniowy, a transmisja wydaje się działać, ale mam problemy z odbieraniem transmisji na drugim urządzeniu.Inicjuję 'DatagramSocket' w ten sam sposób na urządzeniu odbierającym. Próbowałem również użyć adresu wieloznacznego na odbierającym 'DatagramSocket', dodając' InetAddress.getByName ("0.0.0.0") 'jako argument. Brak szczęścia. – KatoStoelen

+0

@ user2190832 dodał trochę więcej szczegółów do mojej odpowiedzi, aby przeczytać UDP. –

+0

Kod działa świetnie, dzięki! Niektóre szczegóły dotyczące urządzeń: Buduję własne biblioteki do obsługi tej komunikacji w oparciu o ten kod. Obecnie korzystam z portu 8888. My Nexus 5 może wysyłać i odbierać. Mój Moto G może tylko wysyłać pakiety (i odbierać własne, ale nie tworzyć innych urządzeń). Niedawno wypróbowałem w Samsung Galaxy S2 i mogę wysyłać i odbierać pakiety. W jakiś sposób Motorola blokuje nadawane wiadomości. Próbowałem w dwóch różnych wersjach MotoG, jednej zgniłej z konkretnymi regułami firewalla i jednym magazynie, ale bez powodzenia. –

Powiązane problemy