技术标签: wifi wi-fi android 局域网 arp Android
目的:获取当前局域网内其他连接设备的IP 和MAC信息。
步骤:
- 获取本机wifi ip信息;
- 根据ip 去发送ARP请求
- 读取本地ARP 表;
####1. 获取本机WiFi 下 ip :参考另一篇文章
####2. ARP 简介
- 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。
- ARP 缓存
ARP缓存是个用来储存IP地址和MAC地址的缓冲区,其本质就是一个IP地址–>MAC地址的对应表,表中每一个条目分别记录了网络上其他主机的IP地址和对应的MAC地址。每一个以太网或令牌环网络适配器都有自己单独的表。当地址解析协议被询问一个已知IP地址节点的MAC地址时,先在ARP缓存中查看,若存在,就直接返回与之对应的MAC地址,若不存在,才发送ARP请求向局域网查询。
为使广播量最小,ARP维护IP地址到MAC地址映射的缓存以便将来使用。ARP缓存可以包含动态和静态项目。动态项目随时间推移自动添加和删除。每个动态ARP缓存项的潜在生命周期是10分钟。新加到缓存中的项目带有时间戳,如果某个项目添加后2分钟内没有再使用,则此项目过期并从ARP缓存中删除;如果某个项目已在使用,则又收到2分钟的生命周期;如果某个项目始终在使用,则会另外收到2分钟的生命周期,一直到10分钟的最长生命周期。静态项目一直保留在缓存中,直到重新启动计算机为止.
普通的 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();
}
}
}
}
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) {
}
}
2019 May 14 头文件, 源文件 头文件和源文件分离 概览 非模板类型(none-template) 模板类型(template) 头文件(.h) 1. 全局变量申明(带 extern 限定符)2. 全局函数的申明3. 带 inline 限定符的全局函数的定义4. 类的定义5. 类函数成员和数据成员的申明(在类内部)6. 类定义内的函数定义(相当于 inline )...
问题描述:在iPhone上调用键盘,用键盘输入时正常没有任何问题,但切换成手写输入法之后,写第二个字的时候会出现闪退崩溃的现象。其原因就在于手写键盘的事件与触摸手势的事件发生了冲突。解决方案:扩展UIView或者UIScrollerView,重写touchesBegan、touchesMoved、touchesEnded方法,屏蔽该3个方法即可。附上我自己写的扩展地址: 链接:http://pan
1.APN:Access Point Name 接入点名称,用来标识GPRS的业务种类,目前分为两大类:CMWAP(通过GPRS访问WAP业务)、CMNET(除了WAP以外的服务目前都用CMNET,比如连接因特网等)。手机默认上网配置一般用于WAP浏览,所以APN接入点普遍默认设置成CMWAP,名称一般叫“移动梦网”(中国移动的品牌),CMNET的接入配置名称一般叫“GPRS连接互联网”之
ORA-12560: TNS: 协议适配器错误的解决方法去掉PLSQL 安装路径包含空格 文件夹包含的空格PLSQL 安装路径包含空格 文件夹包含的空格PLSQL 安装路径包含空格 文件夹包含的空格PLSQL 安装路径包含空格 文件夹包含的空格PLSQL 安装路径包含空格 文件夹包含的空格
前言:python连接mysql数据库需要导入mysql,python2使用的是MySQLdb,python3使用的是pymysql具体操作:一、pycahrm操作二、pip命令1、pip install PyMySQL2、在python中导入pymysql
这几天在使用bootstrap框架的插件时突然忘记了jQuery文件时怎么导入的,接下来就详细讲解以下导入过程。
在WSS3.0中,您可以通过创建一个含有CustomAction元素定义的Feature来为列表项或文档库添加一个自定义菜单项。用这种方式您可以为SharePoint默认用户界面添加自定义控制。这些自定义菜单控制允许用户在列或文档库项上执行自定义操作。例如,您可以为列表或文档库创建一个自定义菜单项,并定向跳转到一个自定义应用程序页.首先,在VS2010中新建一个项目.然后...
查看Linux系统信息arch#显示机器的处理器架构(1)uname -m#显示机器的处理器架构(2)uname -r#显示正在使用的内核版本dmidecode -q#显示硬件系统部件 - (SMBIOS / DMI)hdparm -i /dev/hda#罗列一个磁盘的架构特性hdparm -tT /dev/sda#在磁盘上执行测试性读取操作cat /proc/cp...
这个问题我通过举例来解决: 1、对于浮点数,如果写了以下程序片段:double PI=3.14;这个片段编译时没有问题,但是如果写了以下片段:float PI=3.14;就会出现编译错误,这是因为在程序写下一个浮点数时,编译程序默认会使用double类型,你想要将double长度的数据指定给float类型变量,编译程序就会有错误提示。有两种方式可以避免这个错误:第一种方式
这个教练是你的好朋友,他记录了四个人的跑步十个跑步时间在四个文件里面james.txt ,julie.txt,mikey.txt,sarah.txt2-34,3:21,2.34,2.45,3.01,2:01,2:01,3:10,2-222.59,2.11,2:11,2:23,3-10,2-23,3:10,3.21,3-212:22,3.01,3:01,3.02,3:02...
在gitlab上创建项目dev_lnmp创建项目在jenkins机器上克隆该项目sudo -iyum -y install gitgit config --global user.name "root"git config --global user.email "[email protected]"git clone http://172.16.38.31/root/de...