目的:获取当前局域网内其他连接设备的IP 和MAC信息。
步骤:
1. 获取本机wifi ip信息;
2. 根据ip 去发送ARP请求
3. 读取本地ARP 表;

1. 获取本机WiFi 下 ip :参考另一篇文章

Android 获取设备IP

2. ARP 简介

  1. 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。
  2. ARP 缓存
    ARP缓存是个用来储存IP地址和MAC地址的缓冲区,其本质就是一个IP地址–>MAC地址的对应表,表中每一个条目分别记录了网络上其他主机的IP地址和对应的MAC地址。每一个以太网或令牌环网络适配器都有自己单独的表。当地址解析协议被询问一个已知IP地址节点的MAC地址时,先在ARP缓存中查看,若存在,就直接返回与之对应的MAC地址,若不存在,才发送ARP请求向局域网查询。
    为使广播量最小,ARP维护IP地址到MAC地址映射的缓存以便将来使用。ARP缓存可以包含动态和静态项目。动态项目随时间推移自动添加和删除。每个动态ARP缓存项的潜在生命周期是10分钟。新加到缓存中的项目带有时间戳,如果某个项目添加后2分钟内没有再使用,则此项目过期并从ARP缓存中删除;如果某个项目已在使用,则又收到2分钟的生命周期;如果某个项目始终在使用,则会另外收到2分钟的生命周期,一直到10分钟的最长生命周期。静态项目一直保留在缓存中,直到重新启动计算机为止.
  • 在使用cmd arp -a 命令查看 windows 下arp 表内容

3 在局域网内发送广播

普通的 arp 请求A要和B 建立连接,则 在局域网内发送一个广播 ,发送源A的IP和MAC,目的ip 为B的IP,MAC 信息为 FF:FF:FF:FF:FF:FF(表示广播),但是现在我们不知道局域网内其他设备的ip 信息,因此,只能去逐个发送请求。

// 根据ip 网段去 发送arp 请求
private void discover(String ip) {
String newip = "";
if (!ip.equals("")) {
String ipseg = ip.substring(0, ip.lastIndexOf(".")+1);
for (int i=2; i<255; i++) {
newip = ipseg+String.valueOf(i);
if (newip.equals(ip)) continue;
Thread ut = new UDPThread(newip);
ut.start();
}
}
}
// UDPThread 
public class UDPThread extends Thread {
private String target_ip = "";

public static final byte[] NBREQ = { (byte) 0x82, (byte) 0x28, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1,
(byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x20, (byte) 0x43, (byte) 0x4B,
(byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41,
(byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41,
(byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x41,
(byte) 0x41, (byte) 0x41, (byte) 0x41, (byte) 0x0, (byte) 0x0, (byte) 0x21, (byte) 0x0, (byte) 0x1 };

public static final short NBUDPP = 137;

public UDPThread(String target_ip) {
this.target_ip = target_ip;
}

@Override
public synchronized void run() {
if (target_ip == null || target_ip.equals("")) return;
DatagramSocket socket = null;
InetAddress address = null;
DatagramPacket packet = null;
try {
address = InetAddress.getByName(target_ip);
packet = new DatagramPacket(NBREQ, NBREQ.length, address, NBUDPP);
socket = new DatagramSocket();
socket.setSoTimeout(200);
socket.send(packet);
socket.close();
} catch (SocketException se) {
} catch (UnknownHostException e) {
} catch (IOException e) {
} finally {
if (socket != null) {
socket.close();
}
}
}
}

4 . 读取 ARP 表

private void readArp() {
try {
BufferedReader br = new BufferedReader(
new FileReader("/proc/net/arp"));
String line = "";
String ip = "";
String flag = "";
String mac = "";

while ((line = br.readLine()) != null) {
try {
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);


} catch (Exception e) {
}
}
br.close();

} catch(Exception e) {
}
}


- demo 已上传github打开连接
- 参考 普通ARP请求及回应

更多相关文章

  1. Android图片缓存处理
  2. 如何通过HttpURLConnection得到http 302的跳转地址
  3. 使用drawables的IntelliJ Android缓存构建忽略了更改
  4. Android Studio Gradle 缓存文件夹设置
  5. Java Android套接字连接。错误的IP地址导致应用程序停止响应
  6. Android利用IP地址定位城市(全世界可用)
  7. android NDK 实用学习(四)-类缓存
  8. Android获取WIFI状态下的IP地址以及MAC地址
  9. Android SDK更新以及ADT更新出现问题的解决办法(附google服务器

随机推荐

  1. Android面试系列文章2018之Android部分之
  2. Android中AsyncTask的简单用法及实现网络
  3. Android之分享篇(配图适合新人):腾讯分享(QQ
  4. Android P 图形显示系统(九) Android图形显
  5. android之调用webservice 实现图片上传
  6. Android内核开发:源码的版本与分支详解
  7. Android中View.setPressed是怎么出现按压
  8. Google:Android 2.3在所有Android系统设备
  9. 搭建Android应用程序的服务器
  10. Android游戏Graphics绘图之图像像素操作