it-swarm.com.de

Wie erhalte ich die IP-Adresse jedes Geräts im Wi-Fi Direct-Szenario?

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 die GroupOwner-IP-Adresse nur nach dem Verbinden abgerufen werden kann. Tatsächlich kam jedes Gerät dazu, der GroupOwner zu werden. In der oberen Anwendung müssen wir die IP-Adresse des Peers oder die IP-Adresse jedes Peers in einer Gruppe abrufen, damit wir mit ihnen senden/kommunizieren können.

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

18
nicefuture

Ich bin auf das gleiche Problem gestoßen. Da beide Geräte die IP des Gruppeninhabers kennen, ist es bereits möglich, eine Nachricht an den Gruppeninhaber zu senden. Die erste Nachricht, die Sie senden, kann die IP-Adresse des anderen Geräts enthalten. Von da an ist bidirektionale Kommunikation möglich. 

Hier ist eine Möglichkeit, Ihre IP in Java abzurufen:

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

Wickeln Sie diese IP in ein serialisierbares Objekt und senden Sie es an den Gruppeneigentümer, so wie Sie auch jedes andere Objekt senden würden. Betrachten Sie dies als ersten Schritt in Ihrem WiFi-Direct-Protokoll ... Nun hat der Gruppeneigentümer auch eine IP, an die Antworten gesendet werden sollen.

Dies funktioniert für mich, obwohl ich denke, dass es seltsam ist, dass ich dies selbst implementieren musste und ich nur den Gruppeninhaber ip leicht finden konnte (info.groupOwnerAddress.getHostAddress (); // mit info einer WifiP2pInfo-Instanz). Vielleicht gibt es eine vergleichbare Möglichkeit, die IP-Adresse der anderen Kollegen abzurufen, aber ich konnte sie nicht finden. Bitte nehmen Sie Kontakt mit mir auf.

Viel Glück...

15
Mano

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

Ich bin auf dasselbe Problem gestoßen. Da beide Geräte die IP des Gruppenbesitzers 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. ab dann ist bidirektionale kommunikation möglich.

Hier ist, wie ich es implementiert habe. Wenn ich einen Client über WiFi Direct mit dem Gruppeneigentümer verbinde, erhalte ich die IP-Adresse des Gruppeneigentümers und sende eine Nachricht über einen Socket an den Gruppeneigentümer. So 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 kennen bereits mIP (die IP-Adresse des Gruppenbesitzers) und müssen sich nur für einen mPort entscheiden und die Verbindung in der Gruppe erhalten Besitzer gefällt das:

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, wie z. B. ein Nachrichtenobjekt, das den MAC des Absenders enthält und das verwendet werden kann, um die MAC-IP-Beziehungen zu kennen, da WifiP2pDevice nur MAC und - bereitstellt. InetAddress die IP (Weiß jemand, ob es eine Möglichkeit gibt, die MAC von einem InetAddress -Objekt abzurufen?)

10
scruffy

Ich habe ein Demoprojekt gemacht, das in der Lage ist, jede Geräte-IP abzurufen und Daten von einem Gerät an ein anderes zu senden (Gruppeninhaber sein oder nicht). Die URL ist:

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

Ich hoffe es hilft dir!

BEARBEITEN: Grundsätzlich die IP-Adresse im ARP-Cache nachschlagen:

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;
}
4
ahmontero

Ich konnte in einem WiFi-Direktnetz eine Verbindung herstellen und auf beide Arten senden. Alle Geräte kennen die IP-Adresse des Gruppeninhabers. Wir erhalten die Peer-IP von einem für die Kommunikation erstellten Socket. Irgendwie funktionierte es für mich nicht, die IP vom Sockel auf der Serverseite (beim Gruppeninhaber) zu bekommen. Also sende ich dem Gruppeninhaber die IP des einzelnen Geräts von diesem Gerät aus. Um die IP zu erhalten, erstellen Sie einfach einen Socket, binden Sie ihn an einen beliebigen lokalen Port und rufen Sie die Adresse von diesem Socket ab, und senden Sie ihn an den Eigentümer. Ich habe einen UDP-Socket verwendet, aber er funktioniert gut mit TCP Steckdosen.

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ümers, die wir aus den Verbindungsinformationen erhalten.

2
akhil

Ich habe einen anderen Ansatz!

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

Die einzige Information, die Sie darüber haben, ist, wenn der BroadCast-Empfänger angeschlossen ist und Sie ein Objekt "WifiP2pInfo" erhalten. Dieses Objekt enthält 2 interessante Infos: 

  • Die IP-Adresse des Besitzers (mWifiP2PInfo.groupOwnerAddress). Diese Zeichenfolge beginnt mit "/". Vergiss nicht, es zu entfernen! ;)
  • ob Sie der Eigentümer sind oder nicht (mWifiP2PInfo.isGroupOwner)

Von dem haben Sie alles was Sie brauchen!

Wenn Sie der GroupOwner sind => Auf Verbindung warten

Sonst erstellen Sie eine Verbindung zum Eigentümer mit der IP-Adresse.

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 es kann dir helfen !!!

1
acs-team

Bitte 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
Dipendra