如何在Wi-Fi Direct场景中获取每个设备的IP地址?

从ICS开始,介绍Wi-Fi Direct。 通常情况下,我们使用WifiP2pManager类来操作Wi-Fi Direct,但似乎只能在连接后检索GroupOwner IP地址。 但实际上,任何设备都来协商成为GroupOwner。 在高级应用程序中,我们需要获得对等的IP地址,或者每个对等的IP地址在一个组中,以便我们可以发送/通信它们。

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

Solutions Collecting From Web of "如何在Wi-Fi Direct场景中获取每个设备的IP地址?"

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

这里有一个可能性检索你的ip在java中:

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

将这个ip包装在一个Serializable对象中,并将其发送给组所有者,就像发送任何其他对象一样。 考虑这是你的wifi直接协议的第一步…现在,组的所有者也有IP发送答案。

这适用于我,虽然我觉得很奇怪,我必须自己实现这一点,我只能find组的所有者轻松(info.groupOwnerAddress.getHostAddress(); / /信息一个WifiP2pInfo实例)。 也许有一种可比较的方式来检索其他同行的IP,但我找不到它。 请联系我,如果你这样做。

祝你好运…

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

我遇到了同样的问题。 由于两个设备都知道组主人的IP,所以已经可以向组主人发送消息。 您发送的第一条消息可以包含其他设备的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并接收群组所有者的连接,如下所示:

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

这是我正在使用的实际代码。 我将用一些有用的信息来replace这个消息,比如一个包含发送者MAC的消息对象,它可以用来了解MAC-IP关系,因为WifiP2pDevice只提供MAC和InetAddress的IP(有没有人知道有一种方法可以从InetAddress对象获取MAC?)

我已经做了一个演示项目,能够获得每个设备的ip和发送数据从一个设备到另一个(是小组的所有者或不)。 url是:

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

我希望它可以帮助你!

编辑:基本上在这样的ARPcaching中查找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; } 

我已经能够在WiFi直接networking中连接和发送两种方式。 所有设备都知道组所有者的IP地址。 我们从为通信创build的套接字获取对等IP。 不知何故从服务器端(在集团所有者)的套接字获取IP不适合我。 因此,我从该设备本身向组主机发送单个设备的IP。 要获得IP,只需创build一个套接字并将其绑定到任何本地端口,并从该套接字获取地址并将其发送给所有者。 我使用了一个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是我们从连接信息中获得的组所有者的地址。

我有另一种方法!

在两个(或更多)设备之间创build连接时,不能设置所有者和谁是客户端。

唯一的信息是,当BroadCast接收器连接时,您收到一个对象“WifiP2pInfo”。 这个对象包含2个有趣的信息:

  • 拥有者的IP地址(mWifiP2PInfo.groupOwnerAddress)。 该string以“/”开始。 不要忘记删除它! ;)
  • 如果您是所有者(mWifiP2PInfo.isGroupOwner)

从那里你有你需要的一切!

如果你是groupOwner =>听一个连接

否则用ip地址创build一个到拥有者的连接。

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

跳它可以帮助你!

请使用此方法获取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; } */ }