Android 如何获得每个设备';Wi-Fi Direct场景中的IP地址?

Android 如何获得每个设备';Wi-Fi Direct场景中的IP地址?,android,wifi,android-wifi,wifimanager,wifi-direct,Android,Wifi,Android Wifi,Wifimanager,Wifi Direct,从ICS开始,引入了Wi-Fi Direct。通常,我们使用WifiP2pManager类在Wi-Fi Direct上进行操作,但它似乎只能在连接后检索GroupOwner IP地址。但是,事实上,任何设备都成为了GroupOwner。在上层应用程序中,我们需要获取对等方的IP地址,或者组中每个对等方的IP地址,以便我们可以与它们进行发送/通信 如何在Wi-Fi Direct中获取每个IP地址?是否包括自己的IP地址和组中的每个对等方?我遇到了相同的问题。由于两个设备都知道组所有者的ip,因此已

从ICS开始,引入了Wi-Fi Direct。通常,我们使用
WifiP2pManager
类在Wi-Fi Direct上进行操作,但它似乎只能在连接后检索GroupOwner IP地址。但是,事实上,任何设备都成为了GroupOwner。在上层应用程序中,我们需要获取对等方的IP地址,或者组中每个对等方的IP地址,以便我们可以与它们进行发送/通信


如何在Wi-Fi Direct中获取每个IP地址?是否包括自己的IP地址和组中的每个对等方?

我遇到了相同的问题。由于两个设备都知道组所有者的ip,因此已经可以向组所有者发送消息。您发送的第一条消息可以包含其他设备的ip地址;从那时起,双向通信成为可能

以下是用java检索ip的一种可能性:

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());
private byte[]getLocalIPAddress(){
试试{
对于(枚举en=NetworkInterface.getNetworkInterfaces();en.hasMoreElements();){
NetworkInterface intf=en.nextElement();
对于(枚举Enumeration EnumipAddress=intf.getInetAddresses();EnumipAddress.hasMoreElements();){
InetAddress InetAddress=enumIpAddr.nextElement();
如果(!inetAddress.isLoopbackAddress()){
if(inetAddress instanceof Inet4Address){//Galaxy Nexus.IPv4的补丁易于使用:-)
返回inetAddress.getAddress();
} 
//返回inetAddress.getHostAddress().toString();//Galaxy Nexus返回IPv6
} 
} 
} 
}catch(SocketException ex){
//Log.e(“AndroidNetworkAddressFactory”、“getLocalIPAddress()”,ex);
}catch(NullPointerException ex){
//Log.e(“AndroidNetworkAddressFactory”、“getLocalIPAddress()”,ex);
} 
返回null;
}
私有字符串getDottedDecimalIP(字节[]ipAddr){
//转换为点十进制表示法:
字符串ipAddrStr=“”;
对于(int i=0;i 0){
ipAddrStr+=”;
}
ipAddrStr+=ipAddr[i]&0xFF;
}
返回ipAddrStr;
}
ip=getDottedDecimalIP(getLocalIPAddress());
将此ip包装在可序列化对象中,并将其发送给组所有者,就像发送任何其他对象一样。考虑这是你的WiFi直接协议的第一步…现在,组所有者也有一个IP来发送答案

这对我来说是可行的,尽管我认为我必须自己实现这一点很奇怪,我只能很容易地找到组所有者ip(info.groupOwnerAddress.getHostAddress();//带有WifiP2pInfo实例)。也许有一种类似的方法可以检索其他对等方的ip,但我找不到。如果需要,请与我联系


祝你好运…

我已经完成了一个演示项目,可以获取每个设备的ip,并将数据从一个设备发送到另一个设备(无论是否为组所有者)。网址是:

我希望它能帮助你

编辑:基本上在ARP缓存中查找IP地址,如下所示:

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

你能得到的最好答案可能是来自马诺的:


我遇到了同样的问题。因为两个设备都知道该组 所有者的ip,已经可以向组发送消息 主人。您发送的第一条消息可以包含 其他装置;从那时起,双向通信成为可能

下面是我如何实现它的。当我通过WiFi Direct将客户端连接到组所有者时,我会获取组所有者的ip地址,并通过套接字向组所有者发送消息。比如:

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();
您已经知道mIP(组所有者的IP地址),只需决定一个mPort并接收组所有者的连接,如下所示:

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

这是我正在使用的实际代码。我将用一些有用的信息替换此消息,例如包含发送者MAC的消息对象,它可以用于了解MAC-IP关系,因为WifiP2pDevice仅提供MAC和InetAddressIP(有人知道有没有办法从InetAddress对象获取MAC?

我已经能够在WiFi直连网络中双向连接和发送了。 所有设备都知道组所有者的IP地址。我们从为通信而创建的套接字获取对等IP。以某种方式从服务器端(组所有者)的套接字获取IP不适用于我。因此,我从该设备本身向组所有者发送单个设备的IP。要获取IP,只需创建一个套接字并将其绑定到任何本地端口,然后从该套接字获取地址并发送给所有者。 我使用了UDP套接字,但它与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
是我们从连接信息中获取的组所有者的地址。

请使用此方法获取IP地址

  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; }
         */
    }
public静态字符串getIpAddress(){
试一试{
列表接口=集合
.list(NetworkInterface.getNetworkInterfaces());
/*
*对于(NetworkInterface NetworkInterface:interfaces){Log.v(TAG,
*“接口名称”+networkInterface.getName()+“mac=”+
*getMACAddress(networkInterface.getName());}
*/
用于(网络接口intf:接口){
如果(!getMACAddress(intf.getName()).equalsIgnoreCase(
Globals.thisDeviceAddress){
//Log.v(标记“忽略接口”+intf.getName());
//继续;
}
如果(!intf.getName().包含(“p2p”))
继续;
Log.v(标签,
intf.getName()+“”+getMACAddress(intf.getName());
列表地址=Collections.List(intf
.getInetAddresses());
用于(InetAddress地址:地址){
//日志v(标签“内部”);
如果(!addr.isLoopbackAddress()){