赞
踩
1:通过java运行cmd命令,来通过arp命令获取同一网络下设备信息,对于支持linux 和windows的设备有效,像一些非智能设备,就无力回天了
2:使用android手机通过向子网内所有设备先发送一遍udp包,实现与在线的设备都进行通信一遍,这样对应的路由信息就自动存储在本地手机中,然后在通过读取android 本机的arp缓存表,来获取设备信息
好,下面详细进行第二种方式的描述:
Step1:首先,获取本机所处的子网段,方法详细代码如下:
/** * 获取ip地址 * * @return */ private static String getHostIP() { String hostIp = null; try { //这里以eth0为例 hostIp = getIpAddress("eth0"); } catch (SocketException e) { e.printStackTrace(); } return hostIp; } /** * Get Ip address 自动获取IP地址 * 可以传入eth1,eth0,wlan0,等 * * @throws SocketException */ public static String getIpAddress(String ipType) throws SocketException { String hostIp = null; try { Enumeration nis = NetworkInterface.getNetworkInterfaces(); InetAddress ia = null; while (nis.hasMoreElements()) { NetworkInterface ni = (NetworkInterface) nis.nextElement(); if (ni.getName().equals(ipType)) { Enumeration<InetAddress> ias = ni.getInetAddresses(); while (ias.hasMoreElements()) { ia = ias.nextElement(); if (ia instanceof Inet6Address) { continue;// skip ipv6 } String ip = ia.getHostAddress(); // 过滤掉127段的ip地址 if (!"127.0.0.1".equals(ip)) { hostIp = ia.getHostAddress(); break; } } } } } catch (SocketException e) { e.printStackTrace(); } Log.d(ipType, "get the IpAddress--> " + hostIp + ""); return hostIp; }
Step2:new出一个线程,向网段内所有在线设备发送消息。
/** * 创建一个线程向本地所有ip发送一个数据 */ public static void sendDataToLocal() { //局域网内存在的ip集合 final List<String> ipList = new ArrayList<>(); final Map<String, String> map = new HashMap<>(); //获取本机所在的局域网地址 String hostIP = getHostIP(); int lastIndexOf = hostIP.lastIndexOf("."); final String substring = hostIP.substring(0, lastIndexOf + 1); new Thread(new Runnable() { @Override public void run() { DatagramPacket dp = new DatagramPacket(new byte[0], 0, 0); DatagramSocket socket; try { socket = new DatagramSocket(); int position = 2; while (position < 255) { Log.e("Scanner ", "run: udp-" + substring + position); dp.setAddress(InetAddress.getByName(substring + String.valueOf(position))); socket.send(dp); position++; if (position == 125) { //分两段掉包,一次性发的话,达到236左右,会耗时3秒左右再往下发 socket.close(); socket = new DatagramSocket(); } } socket.close(); } catch (SocketException e) { e.printStackTrace(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }).start(); }
执行完后会自动写入到/proc/net/arp
目录下,如下:
Step3:延时3秒后,读取本机proc/net/arp目录下的内容,得到结果:
/** * 读取/proc/net/arp并且解析出来ip,mac,flag * flag 为0x00说明目前不在局域网内,曾经在过.0x02代表在局域网内 */ public static void readArp() { try { BufferedReader br = new BufferedReader(new FileReader("/proc/net/arp")); String line = ""; String ip = ""; //flag 为0x00说明目前不在局域网内,曾经在过.0x02代表在局域网内 String flag = ""; String mac = ""; if (br.readLine() == null) { Log.e("scanner", "readArp: null"); } while ((line = br.readLine()) != null) { line = line.trim(); if (line.length() < 63) continue; if (line.toUpperCase(Locale.US).contains("IP")) continue; ip = line.substring(0, 17).trim(); flag = line.substring(29, 32).trim(); mac = line.substring(41, 63).trim(); if (mac.contains("00:00:00:00:00:00")) continue; Log.e("scanner", "readArp: mac= " + mac + " ; ip= " + ip + " ;flag= " + flag); } br.close(); } catch (Exception ignored) { } }
打印日志如下
最后附上完整代码
public class DiscoverNetIpUtil{ /** * 获取ip地址 * * @return */ private static String getHostIP() { String hostIp = null; try { //这里以eth0为例 hostIp = getIpAddress("eth0"); } catch (SocketException e) { e.printStackTrace(); } return hostIp; } /** * Get Ip address 自动获取IP地址 * 可以传入eth1,eth0,wlan0,等 * * @throws SocketException */ public static String getIpAddress(String ipType) throws SocketException { String hostIp = null; try { Enumeration nis = NetworkInterface.getNetworkInterfaces(); InetAddress ia = null; while (nis.hasMoreElements()) { NetworkInterface ni = (NetworkInterface) nis.nextElement(); if (ni.getName().equals(ipType)) { Enumeration<InetAddress> ias = ni.getInetAddresses(); while (ias.hasMoreElements()) { ia = ias.nextElement(); if (ia instanceof Inet6Address) { continue;// skip ipv6 } String ip = ia.getHostAddress(); // 过滤掉127段的ip地址 if (!"127.0.0.1".equals(ip)) { hostIp = ia.getHostAddress(); break; } } } } } catch (SocketException e) { e.printStackTrace(); } Log.d(ipType, "get the IpAddress--> " + hostIp + ""); return hostIp; } /** * 创建一个线程向本地所有ip发送一个数据 */ public static void sendDataToLocal() { //局域网内存在的ip集合 final List<String> ipList = new ArrayList<>(); final Map<String, String> map = new HashMap<>(); //获取本机所在的局域网地址 String hostIP = getHostIP(); int lastIndexOf = hostIP.lastIndexOf("."); final String substring = hostIP.substring(0, lastIndexOf + 1); new Thread(new Runnable() { @Override public void run() { DatagramPacket dp = new DatagramPacket(new byte[0], 0, 0); DatagramSocket socket; try { socket = new DatagramSocket(); int position = 2; while (position < 255) { Log.e("Scanner ", "run: udp-" + substring + position); dp.setAddress(InetAddress.getByName(substring + String.valueOf(position))); socket.send(dp); position++; if (position == 125) { //分两段掉包,一次性发的话,达到236左右,会耗时3秒左右再往下发 socket.close(); socket = new DatagramSocket(); } } socket.close(); } catch (SocketException e) { e.printStackTrace(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } /** * 读取/proc/net/arp并且解析出来ip,mac,flag * flag 为0x00说明目前不在局域网内,曾经在过.0x02代表在局域网内 */ public static void readArp() { try { BufferedReader br = new BufferedReader(new FileReader("/proc/net/arp")); String line = ""; String ip = ""; //flag 为0x00说明目前不在局域网内,曾经在过.0x02代表在局域网内 String flag = ""; String mac = ""; if (br.readLine() == null) { Log.e("scanner", "readArp: null"); } while ((line = br.readLine()) != null) { line = line.trim(); if (line.length() < 63) continue; if (line.toUpperCase(Locale.US).contains("IP")) continue; ip = line.substring(0, 17).trim(); flag = line.substring(29, 32).trim(); mac = line.substring(41, 63).trim(); if (mac.contains("00:00:00:00:00:00")) continue; Log.e("scanner", "readArp: mac= " + mac + " ; ip= " + ip + " ;flag= " + flag); } br.close(); } catch (Exception ignored) { } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。