android获取局域网设备的ip和对应的mac地址

近期公司有项目要获取到同一局域网下的设备ip和mac,问了度娘2天,网上大师们的项目不是跑不起来就是没有反应

总结一下大家使用的方法无非就是

1:通过java运行cmd命令,来通过arp命令获取同一网络下设备信息,对于支持linux 和windows的设备有效,像一些非智能设备,就无力回天了

2:使用android手机通过向子网内所有设备先发送一遍udp包,实现与在线的设备都进行通信一遍,这样对应的路由信息就自动存储在本地手机中,然后在通过读取android 本机的arp缓存表,来获取设备信息

好,下面详细进行第二种方式的描述:

Step1:首先,获取本机所处的子网段,方法详细代码如下:

private String getHostIP() {
    String hostIp = null;
    try {
        Enumeration nis = NetworkInterface.getNetworkInterfaces();
        InetAddress ia;
        while (nis.hasMoreElements()) {
            NetworkInterface ni = (NetworkInterface) nis.nextElement();
            Enumeration ias = ni.getInetAddresses();
            while (ias.hasMoreElements()) {
                ia = ias.nextElement();
                if (ia instanceof Inet6Address) {
                    continue;// skip ipv6
                }
                String ip = ia.getHostAddress();
                if (!"127.0.0.1".equals(ip)) {
                    hostIp = ia.getHostAddress();
                    break;
                }
            }
        }
    } catch (SocketException e) {
        Log.i("kalshen", "SocketException");
        e.printStackTrace();
    }
    return hostIp;
}

Step2:new出一个线程,向网段内所有在线设备发送消息

private void sendDataToLoacl() {
    //局域网内存在的ip集合
    final List ipList = new ArrayList<>();
    final Map map = new HashMap<>();

    //获取本机所在的局域网地址
    String hostIP = getHostIP();
    int lastIndexOf = hostIP.lastIndexOf(".");
    final String substring = hostIP.substring(0, lastIndexOf + 1);
    //创建线程池
    //        final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(20);
    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 (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

Step3:延时3秒后,读取本机proc/net/arp目录下的内容,得到结果:

private void readArp() {
    try {
        BufferedReader br = new BufferedReader(
                new FileReader("/proc/net/arp"));
        String line = "";
        String ip = "";
        String flag = "";
        String mac = "";
        tv_main_result.setText("");
        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);
            tv_main_result.append("\nip:" + ip + "\tmac:" + mac);
        }
        br.close();
    } catch (Exception ignored) {
    }
}

Step4:结果展示:

android获取局域网设备的ip和对应的mac地址_第1张图片

附上交友平台传送门:

https://github.com/vayneZheng/getLoaclDevMac

 

你可能感兴趣的:(Android)