¿Cómo obtener la dirección IP de cada dispositivo en el escenario Wi-Fi Direct?

A partir de ICS, se introduce Wi-Fi Direct. Normalmente, usamos la clase WifiP2pManager para operar con Wi-Fi Direct, pero parece que solo puede recuperar la dirección IP de GroupOwner después de conectarse. Pero, en realidad, todos los dispositivos llegaron a negociar para convertirse en GroupOwner. En la aplicación superior, necesitamos obtener la dirección IP del par o la dirección IP de cada par en un grupo para que podamos enviar / comunicarnos con ellos.

¿Cómo obtener cada dirección IP en Wi-Fi Direct? Incluya su propia dirección IP y cada par en el grupo?

    Me encontré con el mismo problema. Como ambos dispositivos conocen la IP del propietario del grupo, ya es posible enviar un mensaje al propietario del grupo. El primer mensaje que envíe puede contener la dirección IP del otro dispositivo; a partir de ese momento, la comunicación bidireccional es posible.

    Aquí hay una posibilidad para recuperar su IP en Java:

     private byte[] getLocalIPAddress() { try { for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { if (inetAddress instanceof Inet4Address) { // fix for Galaxy Nexus. IPv4 is easy to use :-) return inetAddress.getAddress(); } //return inetAddress.getHostAddress().toString(); // Galaxy Nexus returns IPv6 } } } } catch (SocketException ex) { //Log.e("AndroidNetworkAddressFactory", "getLocalIPAddress()", ex); } catch (NullPointerException ex) { //Log.e("AndroidNetworkAddressFactory", "getLocalIPAddress()", ex); } return null; } private String getDottedDecimalIP(byte[] ipAddr) { //convert to dotted decimal notation: String ipAddrStr = ""; for (int i=0; i 0) { ipAddrStr += "."; } ipAddrStr += ipAddr[i]&0xFF; } return ipAddrStr; } ip = getDottedDecimalIP(getLocalIPAddress()); 

    Envuelva esta ip en un objeto Serializable y envíela al propietario del grupo como lo haría con cualquier otro objeto. Considere esto como el primer paso en su protocolo wifi-directo … Ahora, el propietario del grupo también tiene un IP para enviar respuestas.

    Esto funciona para mí, aunque creo que es extraño que tuve que implementarlo yo mismo y solo pude encontrar fácilmente el propietario del grupo ip (info.groupOwnerAddress.getHostAddress (); // con información de una instancia de WifiP2pInfo). Tal vez haya una forma similar de recuperar la ip de los otros pares, pero no pude encontrarla. Por favor contáctame si lo haces.

    Buena suerte…

    La mejor respuesta que puedes obtener es posiblemente la de Mano:

    Me encontré con el mismo problema. Como ambos dispositivos conocen la IP del propietario del grupo, ya es posible enviar un mensaje al propietario del grupo. El primer mensaje que envíe puede contener la dirección IP del otro dispositivo; a partir de ese momento, la comunicación bidireccional es posible.

    Así es como lo implementé. Cuando conecto un cliente al propietario del grupo a través de WiFi Direct, obtengo la dirección IP del propietario del grupo y le envío un mensaje al propietario del grupo sobre un socket. Algo como:

     Socket socket = new Socket(); socket.setReuseAddress(true); socket.connect((new InetSocketAddress(mIP, mPort)), SOCKET_TIMEOUT); OutputStream os = socket.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(new String("BROFIST"); oos.close(); os.close(); socket.close(); 

    Usted ya conoce mIP (la dirección IP del propietario del grupo), y solo tiene que decidir un mPort y recibir la conexión del propietario del grupo de esta manera:

     Socket serverSocket = new ServerSocket(mPort); serverSocket.setReuseAddress(true); Socket client = serverSocket.accept(); ObjectInputStream objectInputStream = new ObjectInputStream(client.getInputStream()); Object object = objectInputStream.readObject(); if (object.getClass().equals(String.class) && ((String) object).equals("BROFIST")) { Log.d(TAG, "Client IP address: "+client.getInetAddress()); } 

    Este es el código real que estoy usando. Voy a reemplazar este mensaje con alguna información útil, como un objeto de mensaje que contenga el MAC del remitente, que se puede utilizar para conocer las relaciones MAC-IP, ya que WifiP2pDevice solo proporciona MAC e InetAddress de la IP (¿Alguien sabe si? hay una forma de obtener el MAC de un objeto InetAddress ?)

    He hecho un proyecto de demostración que puede obtener cada dispositivo ip y enviar datos de un dispositivo a otro (sea el propietario del grupo o no). La url es:

    https://github.com/ahmontero/wifi-direct-demo

    ¡Espero que te ayude!

    EDITAR: Básicamente buscar la dirección IP en la memoria caché ARP de esta manera:

     public static String getIPFromMac(String MAC) { BufferedReader br = null; try { br = new BufferedReader(new FileReader("/proc/net/arp")); String line; while ((line = br.readLine()) != null) { String[] splitted = line.split(" +"); if (splitted != null && splitted.length >= 4) { // Basic sanity check String device = splitted[5]; if (device.matches(".*p2p-p2p0.*")){ String mac = splitted[3]; if (mac.matches(MAC)) { return splitted[0]; } } } } } catch (Exception e) { e.printStackTrace(); } finally { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } 

    Pude conectarme y enviar de ambas maneras en una red WiFi directa. Todos los dispositivos conocen la dirección IP del propietario del grupo. Obtenemos la IP par de un socket creado para la comunicación. De alguna manera, obtener el IP del socket en el lado del servidor (en el dueño del grupo) no funcionó para mí. Entonces, le envío al propietario del grupo la IP del dispositivo individual desde ese dispositivo. Para obtener el IP, simplemente cree un socket y conéctelo a cualquier puerto local, obtenga la dirección de este socket y envíelo al propietario. He usado un socket UDP pero funciona bastante bien con sockets TCP.

     DatagramSocket socket=null; try { socket=new DatagramSocket(); socket.connect((new InetSocketAddress(host, port))); String address=socket.getLocalAddress().getHostAddress(); ByteBuffer bb=ByteBuffer.allocate(2+address.length()); bb.putChar('I'); bb.put(address.getBytes()); DatagramPacket pkt=new DatagramPacket(bb.array(),2+address.length()); socket.send(pkt); Log.d(WiFiDirectActivity.TAG,"address"+address+"dest"+host); Log.d(WiFiDirectActivity.TAG,"send"); } catch (SocketException e) { Log.e(WiFiDirectActivity.TAG,"error socketException"); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (socket != null) { if (socket.isConnected()) { socket.close(); } } 

    host es la dirección del propietario del grupo que obtenemos de la información de conexión.

    ¡Tengo otro enfoque!

    Cuando crea la conexión entre los 2 (o más) dispositivos, no puede establecer quién es el propietario y quién es (son) los clientes.

    La única información que tiene sobre eso es cuando el receptor BroadCast está conectado, usted recibe un objeto “WifiP2pInfo”. Este objeto contiene 2 informaciones interesantes:

    • La dirección IP del propietario (mWifiP2PInfo.groupOwnerAddress). Esta cadena comienza por “/”. ¡No olvides quitarlo! 😉
    • si usted es el propietario o no (mWifiP2PInfo.isGroupOwner)

    ¡De eso tienes todo lo que necesitas!

    Si eres el groupOwner => Escucha la conexión

    De lo contrario, cree una conexión con el propietario con la dirección IP.

     if (mWifiP2PInfo.isGroupOwner) { serverSocket = new ServerSocket(port); socket = serverSocket.accept(); } else { // If the client is not listening when the server create the connection, the connection is not established => Try again int retry = 10; socket = new Socket(); socket.bind(null); do { socket.connect((new InetSocketAddress(mWifiP2PInfo.groupOwnerAddress, port)), 500); retry--; } while (!socket.isConnected() && retry > 0); } 

    Hop, te puede ayudar!

    Por favor, use este método para obtener la dirección IP.

      public static String getIpAddress() { try { List interfaces = Collections .list(NetworkInterface.getNetworkInterfaces()); /* * for (NetworkInterface networkInterface : interfaces) { Log.v(TAG, * "interface name " + networkInterface.getName() + "mac = " + * getMACAddress(networkInterface.getName())); } */ for (NetworkInterface intf : interfaces) { if (!getMACAddress(intf.getName()).equalsIgnoreCase( Globals.thisDeviceAddress)) { // Log.v(TAG, "ignore the interface " + intf.getName()); // continue; } if (!intf.getName().contains("p2p")) continue; Log.v(TAG, intf.getName() + " " + getMACAddress(intf.getName())); List addrs = Collections.list(intf .getInetAddresses()); for (InetAddress addr : addrs) { // Log.v(TAG, "inside"); if (!addr.isLoopbackAddress()) { // Log.v(TAG, "isnt loopback"); String sAddr = addr.getHostAddress().toUpperCase(); Log.v(TAG, "ip=" + sAddr); boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr); if (isIPv4) { if (sAddr.contains("192.168.49.")) { Log.v(TAG, "ip = " + sAddr); return sAddr; } } } } } } catch (Exception ex) { Log.v(TAG, "error in parsing"); } // for now eat exceptions Log.v(TAG, "returning empty ip address"); return ""; } public static String getMACAddress(String interfaceName) { try { List interfaces = Collections .list(NetworkInterface.getNetworkInterfaces()); for (NetworkInterface intf : interfaces) { if (interfaceName != null) { if (!intf.getName().equalsIgnoreCase(interfaceName)) continue; } byte[] mac = intf.getHardwareAddress(); if (mac == null) return ""; StringBuilder buf = new StringBuilder(); for (int idx = 0; idx < mac.length; idx++) buf.append(String.format("%02X:", mac[idx])); if (buf.length() > 0) buf.deleteCharAt(buf.length() - 1); return buf.toString(); } } catch (Exception ex) { } // for now eat exceptions return ""; /* * try { // this is so Linux hack return * loadFileAsString("/sys/class/net/" +interfaceName + * "/address").toUpperCase().trim(); } catch (IOException ex) { return * null; } */ }