注:笔者未学习过计算机网络相关的知识,只是在做socket通信项目时接触到这块知识,对一些名词概念使用不当请多多包涵,本篇文章的目的为提供一个笔者原创的Java网络信息获取工具类,并在一定程度上对这个领域的小白指北。

应用场景

笔者在做一个电脑<-->手机之间进行局域网数据传输的项目,这时就需要调用Java中的socket类,而socket的初始化需要用到对方的ip和端口(当对方为服务端时)。换言之,对于电脑来说,在“电脑开热点手机连接”和“手机开热点电脑连接”两种情况下,我都需要知道手机的ip地址。

在手机端,Android提供了封装好的一个WiFiManager类,通过它能很容易的获取自己和对方的WiFi信息,而通过对“/proc/net/arp”的读取可以得到热点信息,在网上很容易能找到关于它们的代码。

在电脑端,我们可以在Windows的UI界面中看到WiFi的名称和连接热点的设备的名称和ip地址(在“设置->网络和Internet->移动热点”中),但是无法获取WiFi的网关(路由器)的地址。更大的问题是,Java不提供任何像Android中WiFiManager类那样的类,至少我在网上没查到。

Java这条路就算断了,唯一的方向就只有Windows中无敌却又难用的cmd了。笔者通过大量的搜索资料和尝试命令,终于把需要的信息通过cmd获取到了。

为了方便理解,下面的本机(my)指的都是电脑,本机的ip地址称为myIP,与本机进行连接的设备(如手机)称为连接者(connecter),其ip地址称为connecterIP。

相关的cmd命令:

一.WiFi部分

1.获取本机ip:在cmd中使用“ipconfig”命令,“无线局域网适配器 WLAN:”下的“IPv4 地址 . . . . . . . . . . . . :”栏即为本机ip。

2.获取连接的WiFi名称:使用“netsh wlan show interfaces”命令,“SSID”栏即为WiFi名称。

3.获取连接者ip:使用“ARP -a”命令,找到“接口:”后的ip地址为本机ip的部分,下面与本机ip属于同一网段且物理地址不为“ff-ff-ff-ff-ff-ff”的即为连接者ip。

二.热点部分

1.获取本机ip:在cmd中使用“ipconfig”命令,“无线局域网适配器 本地连接”下的“IPv4 地址 . . . . . . . . . . . . :”栏即为本机ip。

2.获取连接者ip:使用“ARP -a”命令,找到“接口:”后的ip地址为本机ip的部分,下面与本机ip属于同一网段且物理地址不为“ff-ff-ff-ff-ff-ff”的即为连接者ip。

3.获取连接者的名称:使用“tracert connecterIP”命令(connecterIP为第二步获得的连接者ip),即可跟踪到连接者的名称。(则与Windows UI界面上显示的名称稍有不同(但不影响对设备的识别),但是笔者还没找到获取UI界面上内容的方法)

笔者在Java中获取cmd输出的信息,使用正则表达式提取出其中的信息,并存储在类的属性中,实现了WiFiManager(WiFi管理器)和HotspotManager(热点管理器)两个工具类。

代码:

1.Cmd类(获取cmd输出的信息)

(修改自https://blog.csdn.net/w405722907/article/details/78610503,在此对该文章作者表示感谢,之前笔者使用的另一个代码有错,读取内容混乱导致笔者浪费了很多时间)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;public class Cmd {public static String command(String cmd){//获取cmd输出try {Process process = Runtime.getRuntime().exec(cmd);//关闭流释放资源if(process != null){process.getOutputStream().close();}InputStream in = process.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(in));StringBuilder result = new StringBuilder();String tmp = null;while ((tmp = br.readLine()) != null) {result.append(tmp+"\r\n");//将tmp内容附加(append)到StringBuilder类中}return result.toString();} catch (IOException e) {// TODO 自动生成的 catch 块e.printStackTrace();return null;}}
}

2.WiFiManager类(需要调用Cmd类的command方法)

import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*** 一个WiFi管理类,用于获取WiFi的信息,用于通信* @see #isWiFiConnected()* @see #getMyIP()* @see #getConnecterIP()* @see #getConnecterMAC()* @see #isConnecterHDCP()* * @author blademaster**/
public class WiFiManager {private boolean isWiFiConnected=false;private String myIP=null;//本机的WiFi ipprivate String connecterIP=null;//本机连接的路由的IPprivate String connecterMAC=null;//本机连接的路由的MACprivate boolean isConnecterHDCP=false;//本机连接的路由是否为HDCP动态public WiFiManager() {// TODO 自动生成的构造函数存根//******************由"ipconfig"获取myIP*********************String str=Cmd.command("ipconfig");str=str+"\r\n";//增加用于确定文字分段的回车//获取“无线局域网适配器 WLAN”段String WLAN_str=null;Pattern pattern = Pattern.compile("无线局域网适配器 WLAN:\r\n\r\n[\\s\\S]*?\r\n\r\n");//设置正则表达形式,[\\s\\S]*?为任意数量字符非贪婪正则表达式Matcher matcher = pattern.matcher(str);//对str进行正则表达式搜索if(matcher.find()){int start = matcher.start();int end = matcher.end();WLAN_str=str.substring(start,end);}if(WLAN_str==null) {return;}//获取myIPpattern = Pattern.compile("IPv4 地址 . . . . . . . . . . . . : ");//设置正则表达形式,[\\s\\S]*?为任意数量字符非贪婪正则表达式matcher = pattern.matcher(WLAN_str);//对str进行正则表达式搜索if(matcher.find()){int end = matcher.end();myIP=WLAN_str.substring(end).split("\r\n")[0];//首先截取匹配到的字符串,然后读到回车,获取ip地址isWiFiConnected=true;}else {isWiFiConnected=false;return;}//当WiFi连接时//******************由"ARP -a"获取connecterIP*********************str=Cmd.command("ARP -a");str=str+"\r\n";//增加用于确定文字分段的回车//获取connecterIPpattern = Pattern.compile("接口: "+myIP+"[\\s\\S]*?类型\r\n");//设置正则表达形式,[\\s\\S]*?为任意数量字符非贪婪正则表达式matcher = pattern.matcher(str);//对str进行正则表达式搜索if(matcher.find()){int end = matcher.end();String connecter_str=str.substring(end).split("\r\n")[0];//首先截取匹配到的字符串,然后读到回车,获取ip地址connecterIP=connecter_str.split("\\s+")[1];//"\\s+"为多个空格的正则表达式connecterMAC=connecter_str.split("\\s+")[2];isConnecterHDCP=connecter_str.split("\\s+")[3].equals("动态") ? true : false;}}/*** 判断WiFi是否连接* @return*/public boolean isWiFiConnected() {return isWiFiConnected;}/*** 返回本机的WLAN ip* @return*/public String getMyIP() {return myIP;}/*** 返回本机连接的设备的ip* @return*/public String getConnecterIP() {return connecterIP;}/*** 返回本机连接的设备的MAC* @return*/public String getConnecterMAC() {return connecterMAC;}/*** 返回本机连接的设备的状态(静态or动态)* @return*/public boolean isConnecterHDCP() {return isConnecterHDCP;}/*** 获取正在连接的WiFi的名称(SSID)* @return*/public static String getConnectingWiFiSSID() {String str=Cmd.command("netsh wlan show interfaces");Pattern pattern = Pattern.compile("SSID[\\s\\S]*?: ");//设置正则表达形式,[\\s\\S]*?为任意数量字符非贪婪正则表达式Matcher matcher = pattern.matcher(str);//对str进行正则表达式搜索if(matcher.find()){int end = matcher.end();String SSID=str.substring(end).split("\r\n")[0];//首先截取匹配到的字符串,然后读到回车,获取ip地址return SSID;}return null;}
}

3.HotspotManager类(需要调用Cmd类的command方法)

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 一个热点管理类,用于获取热点的信息,用于通信* @see #isHotspotConnected()* @see #getMyIP()* @see #getConnecterIP()* @see #getConnecterMAC()* @see #isConnecterHDCP()* * @author blademaster**/
public class HotspotManager {private boolean isHotspotConnected=false;private ArrayList<String> localIP=new ArrayList<>();//所有本地连接的地址private ArrayList<String> myIP=new ArrayList<>();//本机的ip,与connecterIP对应private ArrayList<String> connecterName=new ArrayList<>();//解析的主机名称private ArrayList<String> connecterIP=new ArrayList<>();//连接本机的设备的IPprivate ArrayList<String> connecterMAC=new ArrayList<>();//连接本机的设备的MACprivate ArrayList<Boolean> isConnecterHDCP=new ArrayList<>();//连接本机的设备是否为HDCP动态,boolean为数据类型,不属于对象,不能作为ArrayList的类型public HotspotManager() {// TODO 自动生成的构造函数存根//******************由"ipconfig"获取myIP*********************String str=Cmd.command("ipconfig");str=str+"\r\n";//增加用于确定文字分段的回车//获取“无线局域网适配器 本地连接”段,由于可能存在多个本地连接,查找所有可能的本地连接ArrayList<String> Local_str=new ArrayList<>();Pattern pattern = Pattern.compile("无线局域网适配器 本地连接[\\s\\S]*?\r\n\r\n[\\s\\S]*?\r\n\r\n");//设置正则表达形式,[\\s\\S]*?为任意数量字符非贪婪正则表达式Matcher matcher = pattern.matcher(str);//对str进行正则表达式搜索while(matcher.find()){int start = matcher.start();int end = matcher.end();Local_str.add(str.substring(start,end));}// 获取myIPfor (int i = 0; i < Local_str.size(); i++) {pattern = Pattern.compile("IPv4 地址 . . . . . . . . . . . . : ");// 设置正则表达形式,[\\s\\S]*?为任意数量字符非贪婪正则表达式matcher = pattern.matcher(Local_str.get(i));// 对str进行正则表达式搜索if (matcher.find()) {int end = matcher.end();localIP.add(Local_str.get(i).substring(end).split("\r\n")[0]);// 首先截取匹配到的字符串,然后读到回车,获取ip地址} }if(localIP.isEmpty()) {isHotspotConnected = false;return;}//当热点连接时//******************由"ARP -a"获取connecterIP*********************str=Cmd.command("ARP -a");str=str+"\r\n";//增加用于确定文字分段的回车for (int i = 0; i < localIP.size(); i++) {// 获取connecterIPpattern = Pattern.compile("接口: " + localIP.get(i) + "[\\s\\S]*?类型\r\n");// 设置正则表达形式,[\\s\\S]*?为任意数量字符非贪婪正则表达式matcher = pattern.matcher(str);// 对str进行正则表达式搜索if (matcher.find()) {int start = matcher.end();pattern = Pattern.compile("接口: " + localIP.get(i) + "[\\s\\S]*?类型\r\n[\\s\\S]*?\r\n\r\n");// 设置正则表达形式,[\\s\\S]*?为任意数量字符非贪婪正则表达式matcher = pattern.matcher(str);// 对str进行正则表达式搜索if (matcher.find()) {//注意要先matcher.find()才能调用matcher.end()int end = matcher.end()-4;// 除去两个回车(一个"\r\n"两个)String connecter_str = str.substring(start, end);// 首先截取匹配到的字符串,然后读到回车,获取ip地址String[] connecter_tag=connecter_str.split("\r\n");int n=0;while(!connecter_tag[n].split("\\s+")[2].equals("ff-ff-ff-ff-ff-ff")) {//应该添加局域网的判断,此处省略myIP.add(localIP.get(i));connecterIP.add(connecter_tag[n].split("\\s+")[1]);// "\\s+"为多个空格的正则表达式connecterMAC.add(connecter_tag[n].split("\\s+")[2]);isConnecterHDCP.add(connecter_tag[n].split("\\s+")[3].equals("动态") ? true : false);isHotspotConnected = true;//找到至少一个真实的连接者n++;}}}}for(int i=0;i<connecterIP.size();i++) {connecterName.add(IP2Hostname(connecterIP.get(i)));//由连接设备的ip解析出设备名}}/*** 判断热点是否有设备接入* @return*/public boolean isHotspotConnected() {return isHotspotConnected;}/*** 返回本机的本地连接ip(可能有多个)* @return*/public ArrayList<String> getMyIP() {return myIP;}/*** 返回连接本机热点的设备的ip(可能有多个)* @return*/public ArrayList<String> getConnecterIP() {return connecterIP;}/*** 返回连接本机热点的设备的MAC(可能有多个)* @return*/public ArrayList<String> getConnecterMAC() {return connecterMAC;}/*** 返回连接本机热点的设备的状态(静态or动态)(可能有多个)* @return*/public ArrayList<Boolean> isConnecterHDCP() {return isConnecterHDCP;}/*** 返回连接本机热点的设备的主机名称(可能有多个)* @return*/public ArrayList<String> getConnecterName() {return connecterName;}/*** 将热点连接设备的ip通过tracert命令解析为主机名* @param ip* @return*/public static String IP2Hostname(String ip) {String str=Cmd.command("tracert "+ip);if(str.split("\\s+").length < 17) {//当未跟踪到主机名时return null;}String hostname=str.split("\\s+")[15];//通过对cmd输出分析得到hostname=hostname.split("\\.")[0];//去除.mshome.net后缀return hostname;}
}

使用方法:

1.WiFiManager类

通过“WiFiManager wiFiManager=new WiFiManager();”即可创建已获得WiFi信息的对象,然后调用其方法即可获取信息。

由于一般电脑只能连接一个WiFi,所以其对应的信息一般只有一个,返回的信息为String对象

2.HotspotManager类

通过“HotspotManager hotspotManager=new HotspotManager();”即可创建已获得热点信息的对象,然后调用其方法即可获取信息。

由于一台电脑的热点至多可供8台设备连接,所以connecterIP等信息可能不为一个,笔者返回的是ArrayList类的数据,这样便于管理和使用(不懂ArrayList类的同学可以查一下,使用起来非常简单)。

[Java]一个WiFi管理器(获取WiFi连接的网关的ip和信息)和热点管理器(获取连接本机的热点的设备的ip、MAC和信息)相关推荐

  1. 计算机网络不同层中用于将网络互连的中间设备——转发器、网桥(桥接器)、路由器、网关

    计算机网络不同层中用于将网络互连的中间设备--转发器.网桥(桥接器).路由器.网关 转发器--物理层 网桥(桥接器)--数据链路层 路由器--网络层 网关--网络层以上 转发器--物理层 网桥(桥接器 ...

  2. Java获取WiFi ssid_如何在Flutter中获取当前连接的wifi的wifi名称(SSID)

    在这个Connectivity Plugin的帮助下,我能够使用以下代码获得连接状态,即移动网络,wifi或无: import 'dart:async'; import 'package:flutte ...

  3. java 获取wifi_获取wifi列表并连接wifi

    一.获取wifi列表 获取wifi列表需要用wifiManager.startScan();进行扫描,扫描结果的列表使用List 保存 扫描步骤: wifiManager.startScan(); / ...

  4. java 获取wifi强度_Android获取当前已连接的wifi信号强度的方法

    本文实例讲述了Android获取当前已连接的wifi信号强度的方法,是Android程序开发中非常常见的重要技巧.分享给大家供大家参考之用.具体方法如下: 1.得到当前已连接的wifi信息 WifiM ...

  5. 怎样使用C# 获取WIFI的连接状态?

    怎样使用C# 获取WIFI的连接状态? 行文导航 思路 问题得到解决 代码展示 断开与连接WIFI状态效果 在OrangePI Linux Arm32上的测试效果 C# 获取WIFI的连接状态 本文是 ...

  6. android 获取wifi信号强度,获取wifi当前手机连接的wifi信息以及信号强度

    1.获得WifiManager对象WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIF ...

  7. 获取wifi当前手机连接的wifi信息以及信号强度

    修改时间:2022/9/5 案例中是主动向安卓系统获取wifi信号强度,正常情况下是通过监听广播的方式来被动获取,看自己三年前写的代码还是挺好笑的,看到好多问题,再不改就误人子弟了,所以改了改. 给权 ...

  8. python自动化扫描,多线程枚举获取wifi信息,让你走在任何一个地方都能上网

    python自动化扫描,多线程枚举获取wifi信息,让你走在任何一个地方都能上网. 无线网络在无线局域网的范畴是指"无线相容性认证",实质上是一种商业认证,同时也是一种无线联网技术 ...

  9. Android7.0+ 获取WiFi列表以及连接WiFi

    获取WiFi列表并连接 这段时间项目中涉及到需要获取WiFi列表以及连接,在这里记录下 其中就有一个坑,在Android7.0以上还需要打开定位(也就是手机中"位置信息") Wif ...

  10. android 获取wifi的加密类型,Android WIFI开发:获取wifi列表,连接指定wifi,获取wifi加密方式,监听wifi网络变化等...

    下面是 Android 开发中 WiFi 的常用配置,如:获取当前 WiFi ,扫描 WiFi 获取列表,连接指定 WiFi ,监听网络变化等等. 下面是效果图: GitHub 下载地址:https: ...

最新文章

  1. Android笔记——四大组件详解与总结
  2. 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(4月7日)...
  3. Virtex-6器件的时钟资源、混合模式时钟管理器(MMCM)
  4. Informix存储过程
  5. dart string 转 bool_Dart语法篇之集合操作符函数与源码分析(三)
  6. c语言编程车,C语言编程之自动类型转化
  7. POJ 3276 Face The Right Way 反转
  8. mysql8连接 2002_ERROR 2002 mysql连接失败 解决方法
  9. 菜鸟教程html5常用标签,HTML5 Canvas | w3cschool菜鸟教程
  10. thinkpad卡在logo界面_win7系统开机卡在Thinkpad LOGO画面无法进入桌面的解决方法
  11. 浅析轻量化网络mobilenet
  12. 10万辆特斯拉之后,租车公司Hertz再订6.5万辆Polestar电动车
  13. 如何在Digital Ocean VPS上安装cpanel / whm
  14. 成都拓嘉启远:拼多多补单套券的危害
  15. 《802.11无线网络权威指南》摘录
  16. SpringCloud Feign参数传递问题
  17. python编写一元二次方程求根公式复数,VB:一元二次方程算法中求根公式如何做复数处理?...
  18. 当for循环和remove一起使用会出现的问题
  19. 宠物精灵2-卡片类连连看游戏
  20. mac如何远程连接windows

热门文章

  1. 内外双修,人剑合璧——IT运维人员的九阳神功(大结局)
  2. simplest_ffmpeg_decoder_pure.c
  3. 关于常用传感器NPN和PNP类型的选择
  4. c语言案例六 速算24,参阅:C语言速算24数据结构课程设计最终版
  5. DRF框架(十四)——过滤Filtering,排序
  6. 小象学院python网课值得吗-小象学院Python数据分析第二期【升级版】
  7. 网络接口 FE GE 10GE SFP
  8. 无线控制需要服务器,无线局域网无线控制器管理用户通过RADIUS服务器认证的配置-Cisco.PDF...
  9. Uiuc计算机博士面试时间,学霸分享:UIUC生物博士onsite面试经验
  10. Linux下 Android adb驱动