Android 查询局域网内所有ip和mac地址

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

猜你喜欢

转载自blog.csdn.net/weixin_44232136/article/details/129190102