2012-04-07 13 views
18

Ausgehend von ICS wird Wi-Fi Direct eingeführt. Normalerweise verwenden wir die Klasse WifiP2pManager, um mit Wi-Fi Direct zu arbeiten, aber es scheint, dass sie die GroupOwner-IP-Adresse nur abrufen kann, nachdem sie verbunden wurde. Aber tatsächlich, jedes Gerät kam, um der GroupOwner zu werden. In Upper Application müssen wir die IP-Adresse des Peers oder die IP-Adresse jedes Peers in einer Gruppe erfassen, damit wir mit ihnen kommunizieren können.Wie bekomme ich die IP-Adresse jedes Geräts im Wi-Fi Direct-Szenario?

Wie erhalten Sie jede IP-Adresse in Wi-Fi Direct? Eigene IP-Adresse und jeden Peer in die Gruppe aufnehmen?

Antwort

13

Ich stieß auf das gleiche Problem. Da beide Geräte die IP des Gruppeneigentümers kennen, ist es bereits möglich, eine Nachricht an den Gruppenbesitzer zu senden. Die erste Nachricht, die Sie senden, kann die IP-Adresse des anderen Geräts enthalten. von da an ist eine bidirektionale Kommunikation möglich.

Hier ist eine Möglichkeit für Ihre IP in Java abrufen:

private byte[] getLocalIPAddress() { 
    try { 
     for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { 
      NetworkInterface intf = en.nextElement(); 
      for (Enumeration<InetAddress> 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<ipAddr.length; i++) { 
     if (i > 0) { 
      ipAddrStr += "."; 
     } 
     ipAddrStr += ipAddr[i]&0xFF; 
    } 
    return ipAddrStr; 
} 

ip = getDottedDecimalIP(getLocalIPAddress()); 

Wrap diese ip in einem Serializable Objekt und an den Gruppeneigentümer senden wie jedes andere Objekt schicken würde. Betrachten Sie dies als den ersten Schritt in Ihrem WLAN-Direktprotokoll ... Jetzt hat der Gruppenbesitzer auch eine IP, an die er Antworten senden kann.

Das funktioniert für mich, obwohl ich finde, dass es komisch ist, dass ich das selbst implementieren musste und ich den Gruppenbesitzer ip einfach finden konnte (info.groupOwnerAddress.getHostAddress(); // mit einer WifiP2pInfo-Instanz). Vielleicht gibt es einen vergleichbaren Weg, um die IP der anderen Peers zu erhalten, aber ich konnte es nicht finden. Bitte kontaktieren Sie mich, wenn Sie das tun.

Viel Glück ...

+1

Warnung: Dieser Code gibt die erste IP-Adresse zurück, die nicht die Loopback ist, wenn Sie mit einem WLAN-Zugangspunkt sowie WLAN direkt verbunden sind, ist es möglich, dass es die Adresse des Access Points zurückgibt. Von dem, was ich gesehen habe, ist das Netzwerk von Wifi Direct verwendet 192.168.49.0 Bereich, so sollten Sie überprüfen, ob es in diesem Bereich oder besser noch die Host-Adresse des Besitzers zu vergleichen, um sicherzustellen, dass sie im selben Netzwerk sind. – triggs

+0

Aus dem letzten Forum Post habe ich herausgefunden, dass es möglich ist, Client-IP vom Master (Gruppenbesitzer) zu bekommen, wenn ich eine TCP-Verbindung erstellen kann. Aber für UDP-Verbindung, wie wird es möglich, Client-IP-Adresse zu bekommen? Vielen Dank. – user1850484

4

Ich habe ein Demo-Projekt durchgeführt, die jedes Gerät ip und senden Daten von einem Gerät zu einem anderen (sein der Gruppeneigentümer oder nicht) zu erhalten vermag. Die URL ist:

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

Ich hoffe, es hilft Ihnen!

EDIT: Im Grunde sucht die IP-Adresse in ARP-Cache wie folgt auf:

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; 
} 
+5

diese Methode ist von Projekt von URL, die Sie unterstellen ... Ich habe versucht, diese App verwenden .. aber, es hat nicht funktioniert ... zwei andere Abstürze war passiert .. Ich kann nicht empfehlen, versuchen, diese Methode jemand zu verwenden ... weil er immer Null zurückgibt. –

+0

In diesem konnte ich nur die Werte des verbundenen WLAN-Netzwerkes abrufen. Es liefert nicht die Werte von WiFi Direct. – Teja

+0

Das ist Code funktioniert gut. Ich kann die verbundene WiFi Direct IP Adresse abrufen. – Teja

9

Die beste Antwort, die Sie erhalten können, ist möglicherweise die man von Mano:

ich das gleiche Problem aufgetreten. Da beide Geräte die IP-Adresse des Besitzers der Gruppe kennen, ist es bereits möglich, eine Nachricht an die Gruppe Eigentümer zu senden. Die erste Nachricht, die Sie senden, kann die IP-Adresse des anderen Geräts enthalten; von da an ist eine bidirektionale Kommunikation möglich.

Hier ist, wie ich es implementiert habe. Wenn ich einen Client über WiFi Direct mit dem Gruppenbesitzer verbinde, erhalte ich die IP-Adresse des Gruppeninhabers und sende über einen Socket eine Nachricht an den Gruppenbesitzer.Etwas wie:

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

Sie wissen bereits mIP (die IP-Adresse der Gruppe Eigentümer), und nur zu entscheiden, haben eine mPort und erhalten die Verbindung auf dem Gruppeneigentümer wie folgt aus:

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

Dies ist der eigentliche Code, den ich verwende. Ich werde diese Nachricht durch einige nützliche Informationen ersetzen, z. B. ein Nachrichtenobjekt mit dem MAC des Absenders, das verwendet werden kann, um MAC-IP-Beziehungen zu kennen, da WifiP2pDevice nur MAC und InetAddress weiß jemand, ob es ein Weg, um den MAC aus einem InetAddress Objekt zu bekommen?)

2

ich habe in der Lage, beiden Möglichkeiten in einem WiFi direkten Netzwerk zu verbinden und zu senden. Alle Geräte kennen die IP-Adresse des Gruppenbesitzers. Wir erhalten die Peer-IP von einem Socket, der für die Kommunikation erstellt wurde. Irgendwie funktionierte die IP aus dem Socket auf der Serverseite (beim Gruppenbesitzer) nicht. Also sende ich dem Gruppenbesitzer die IP des einzelnen Geräts von diesem Gerät selbst. Um die IP zu erhalten, erstellen Sie einfach einen Socket und binden ihn an jeden lokalen Port und holen die Adresse von diesem Socket und senden sie an den Besitzer. Ich habe einen UDP-Socket verwendet, aber es funktioniert gut genug mit TCP-Sockets.

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 ist die Adresse des Gruppeneigentümer wir von den Verbindungsinformationen erhalten.

+0

Danke. Ich habe Host-IP, aber was muss ich in Port-Nummer eingeben. In der App verwende ich 8000. Kann ich es benutzen? – Teja

0

Verwenden Sie diese Methode, um die IP-Adresse zu erhalten.

public static String getIpAddress() { 
    try { 
     List<NetworkInterface> 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<InetAddress> 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<NetworkInterface> 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; } 
     */ 
    } 
+0

gut. Da Sie nun wissen, wie Sie eine eigene IP-Adresse finden, lautet Ihre IP-Adresse entweder 192.168.69.1 (Server) oder 192.168.69. * (Client). Wenn das Gerät eine Server-IP erhält, richten Sie den Server-Socket auf diesem Gerät ein und versuchen Sie, eine Verbindung mit diesem Server-Socket über das Gerät herzustellen, das die Client-IP erhält. Nachdem Sie auf diese Weise eine TCP-Verbindung hergestellt haben, können Sie alle Informationen, die Sie benötigen, auf zwei Arten übertragen. Es kann IP-Adresse, MAC-Adresse, Dateien usw. sein. Alles ist jetzt für Sie. Prost. – Dipendra

+0

Korrektur: Ich kann meine Wi-Fi-IP-Adresse 192.168.49.1 bekommen, wenn ich die Gruppe Owner bin. aber wenn ich ein Klient bin, kann ich meine eigene wifi-direkte IP-Adresse nicht bekommen. Es ist sehr wichtig, die IP-Adresse des Clients zu kennen, so dass es möglich ist, diese Information an den Gruppenbesitzer zu senden. – user1850484

+0

Wenn die Verbindung hergestellt ist, wird diese Funktion zu 99% die IP-Adresse eines Ihrer wifi direkten Geräts abrufen. – Dipendra

1

Ich habe einen anderen Ansatz!

Wenn Sie die Verbindung zwischen den 2 (oder mehr) Geräten erstellen, können Sie nicht festlegen, wer der Eigentümer ist und wer die Clients sind.

Die einzige Information, über die Sie verfügen, wenn der BroadCast-Empfänger verbunden ist, erhalten Sie ein Objekt "WifiP2pInfo". Dieses Objekt enthält zwei interessante Infos:

  • Der Besitzer IP-Adresse (mWifiP2PInfo.groupOwnerAddress). Diese Zeichenfolge beginnt mit "/". Vergessen Sie nicht, es zu entfernen! ;)
  • wenn Sie der Eigentümer sind oder nicht (mWifiP2PInfo.isGroupOwner)

Von, dass Sie alles haben, was Sie brauchen!

Wenn Sie die GrEigentümer sind => Listen für eine Verbindung

Else eine Verbindung mit dem Eigentümer der IP-Adresse erstellen.

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 kann Ihnen helfen !!!