Android/uni-app讀取局域網所有IP&MAC

一.創建一個讀取局域網ip的工具類IPUtils

參考自: https://gitee.com/kalshen/IpScanner/blob/master/app/src/main/java/com/yoofn/ipscanner/IpScanner.java

稍微有些修改,不過大致一致,只是輸出爲Map修改爲字符串

package io.dcloud.HBuilder.ip;

import android.os.Handler;
import android.os.Looper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by kalshen on 2017/7/5 0005.
 * ip 掃描類
 */

public class IPUtils {
    private Handler mHandler = new Handler(Looper.getMainLooper());//獲取主線程的Looper
    private OnScanListener listener;

    /**
     * 獲取局域網中的 存在的ip地址及對應的mac
     */
    public void startScan() {
        //局域網內存在的ip集合
        final List<String> ipList = new ArrayList<>();
        final Map<String, String> map = new HashMap<>();

        //獲取本機所在的局域網地址
        //192.168.43.38
        String hostIP = getHostIP();
        int lastIndexOf = hostIP.lastIndexOf(".");
        //192.168.43.
        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) {
                        dp.setAddress(InetAddress.getByName(substring + String.valueOf(position)));
                        socket.send(dp);
                        position++;
                        if (position == 125) {//分兩段掉包,一次性發的話,達到236左右,會耗時3秒左右再往下發
                            socket.close();
                            socket = new DatagramSocket();
                        }
                    }
                    socket.close();
                    execCatForArp();
                } catch (SocketException e) {
                    e.printStackTrace();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 執行 cat命令 查找android 設備arp表
     * arp表 包含ip地址和對應的mac地址
     */
    private void execCatForArp() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    final StringBuilder stringBuilder = new StringBuilder();
                    Process exec = Runtime.getRuntime().exec("cat proc/net/arp");
                    InputStream is = exec.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        if (!line.contains("00:00:00:00:00:00")&&!line.contains("IP")) {
                            String[] split = line.split("\\s+");
                            stringBuilder.append(split[3]).append(",").append(split[0]).append("|");
                        }
                    }
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            listener.scan(stringBuilder.toString());
                        }
                    });

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 獲取本機 ip地址
     *
     * @return
     */
    private String getHostIP() {

        String hostIp = null;
        try {
            Enumeration nis = NetworkInterface.getNetworkInterfaces();
            InetAddress ia;
            while (nis.hasMoreElements()) {
                NetworkInterface ni = (NetworkInterface) nis.nextElement();
                Enumeration<InetAddress> 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) {
            e.printStackTrace();
        }
        return hostIp;

    }

    public void setOnScanListener(OnScanListener listener) {
        this.listener = listener;
    }

    interface OnScanListener {
        void scan(String ips);
    }

}

如果是打包Android那麼需要放在Android項目的java目錄下 例如:

二 .HBuilderX的項目中新增調用java獲取局域網IP的類IPUtils

 utils.js文件內容

/**fileName:utils.js
 *
 */
const fun = 'function';
/**獲取局域網所有ip
 * 
 */
export function getIPs(success){
	var IPUtils = plus.android.newObject("io.dcloud.HBuilder.ip.IPUtils");
	//獲取arp地址及mac信息
	var hevent = plus.android.implements( "io.dcloud.HBuilder.ip.IPUtils$OnScanListener", {
		"scan":function(resultMap){
			if(success&&typeof success === fun){
				success(JSON.stringify(resultMap))
			}
		}
	} );
	//設置接口信息
	plus.android.invoke(IPUtils,'setOnScanListener',hevent);
	//刷新arp緩存
	plus.android.invoke(IPUtils,'startScan');
}

  顯示局域網列表的vue文件 ip-list.vue

   1.導入上邊的utils.js文件的方法

	import {getIPs} from '@/src/utils/utils.js'

    2.使用工具類方法

getIPs(function(ips){
	if(ips){
		ips = ips.substring(1,ips.length-1)
		ips = ips.split("|");
		if(ips.length >0){
			for (var i = 0; i < ips.length; i++) {
				let ip = ips[i];
				if(ip&&ip.length>0){
					const ipp = ip.split(",");
					const obj = {
						key: ipp[0],
						value:ipp[1],
						sort:ipp[1].substring(ipp[1].lastIndexOf(".")+1,ipp[1].length)
					}
					that.ips.push(obj);
				}
			}
			// 排序
			that.ips=that.ips.sort(function(a,b){return a.sort-b.sort;});
		}
	}
	
});

3.vue文件內容

<template>
	<view>
		<scroll-view >
			<view class="separate">
				<text>地址列表</text>
			</view>
			<view>
				<t-table  border-color="#95b99e">
					<t-tr font-size="14" color="#95b99e" align="left">
						<t-th align="left">序號</t-th>
						<t-th align="left">MAC</t-th>
						<t-th align="left">IP</t-th>
					</t-tr>
					<t-tr font-size="12" color="#5d6f61" align="right" v-for="(item,index) in ips" :key="index">
						<t-td align="left">{{ index+1 }}</t-td>
						<t-td align="left">{{ item.key }}</t-td>
						<t-td align="left">{{ item.value }}</t-td>
					</t-tr>
				</t-table>
			</view>
		</scroll-view>
	</view>
</template>

<script>
	import {getIPs} from '@/src/utils/utils.js'
	import tTable from '@/components/t-table/t-table.vue';
	import tTh from '@/components/t-table/t-th.vue';
	import tTr from '@/components/t-table/t-tr.vue';
	import tTd from '@/components/t-table/t-td.vue';
	
	export default {
		data() {
			return {
				ips:[]
			}
		},
		components: {
			tTable,
			tTh,
			tTr,
			tTd
		},
		created:function(){
			this.getIP();
		},
		methods: {
			getIP:function(){
				const that = this;
				getIPs(function(ips){
					if(ips){
						ips = ips.substring(1,ips.length-1)
						ips = ips.split("|");
						if(ips.length >0){
							for (var i = 0; i < ips.length; i++) {
								let ip = ips[i];
								if(ip&&ip.length>0){
									const ipp = ip.split(",");
									const obj = {
										key: ipp[0],
										value:ipp[1],
										sort:ipp[1].substring(ipp[1].lastIndexOf(".")+1,ipp[1].length)
									}
									that.ips.push(obj);
								}
							}
							// 排序
							that.ips=that.ips.sort(function(a,b){return a.sort-b.sort;});
						}
					}
					
				});
			}
		}
	}
</script>

<style>
	page {
			display: flex;
			flex-direction: column;
			box-sizing: border-box;
			background-color: #efeff4;
	}
			
	.item {
		  background-color:#C8C7CC;
		  margin-top:5px;
	}
	
	.separate {
		  margin-top: 11px;
		  padding-left:5px;
		  padding-top:25px;
		  padding-bottom:25px;
		  background-color: #ffffff;
		  border-bottom: 1px #f5f5f5 solid;
	}
	
	.separate >text {
		  border-left:#4e92df solid 2px;
		  padding-left:10px;
		  color: #464e52;
		  font-size: 17px;
	}
</style>

效果圖:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章