博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
获取系统的网络状态与无线网的信号强度(格数)
阅读量:6642 次
发布时间:2019-06-25

本文共 6094 字,大约阅读时间需要 20 分钟。

一台电脑,有时通过有线网连接网络(调制解调器/局域网),如有网卡也可连接wifi。

那么如何获取WLAN是否连接,和相应的信号强度呢?

就以下俩点:

  • 获取电脑连网状态
  • 获取无线网络的信号强度

 获取电脑连网状态

 1. InternetGetConnectedState

  • 此函数获取网络状态有延时,且对网卡伤害较大
  • MSDN官方自己推荐不建议使用,不管是连网状态下还是断网情况下,获取的网络状态都有不准确的案例,如下:

  

  

  

  

在看下文之前,可以浏览MSDN:

如上InternetGetConnectedState方法介绍中

  • dwReversed必须设置为0
  • 通过输出值lpdwFlags可以获取当前网络连接的信息,通过拼装对比可以得到当前连接的网络类型,如拨号上网/局域网等
bool InternetGetConnectedState( out LPDWORD lpdwFlags, int dwReversed);

首先,添加非托管函数并调用,可以获取网络是否联网

//声明外部的函数[DllImport("winInet.dll ")]private static extern bool InternetGetConnectedState(ref int flag,int dwReserved);

 2. IsNetworkAlive

需要服务System Event Notification的支持(系统默认自动启动该服务),且需要安装最新的SDK(如.NET)

浏览:

由API中翻译:该功能可在Windows XP、2000(或Windows NT 4.0与Internet Explorer 5或更高版本)上使用,在windows95或更高版本上使用Internet Explorer 5或更高版本。所以,一般的系统都是支持的

输出值lpdwFlags

具体类型的详细内容可链接

  • NETWORK_ALIVE_LAN=1 局域网(此处并非指有线网)
  • NETWORK_ALIVE_WAN=2 远程访问-拨号访问和vpn访问(此处并非只无线网,按DPI所示,指的是RAS connections)
  • NETWORK_ALIVE_AOL=4 无效的值。。。因为只有Win9x系统才有此第三个选项。

所以,lpdwFlags对是否无线网络,判断并不准确。

eg:无论是有线还是无线,如下图,我获取的值是1!1指的是局域网~~~

返回值(bool)

  • 当返回值为true,且无错误Code时,表示网络已连接
  • 当返回值为false,且无错误Code时,表示网络未连接

那么,错误Code(异常)怎么获取呢?

3. 获取上一次异常Code-GetLastError

此处推荐使用Marshal中的GetLastWin32Error,见如下源代码:

1     ///  2     ///   通过使用平台调用的最后一个非托管函数返回的错误代码返回调用具有 
标志设置。 3 ///
4 ///
最后一个错误代码设置通过调用 Win32 SetLastError 函数。
5 [SecurityCritical] 6 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 7 [MethodImpl(MethodImplOptions.InternalCall)] 8 public static extern int GetLastWin32Error();

GetLastWin32Error可获取最后一个非托管函数的错误Code

 int errCode = Marshal.GetLastWin32Error();

--获取 error code的详细描述信息,可参考

值得注意的是,非托管函数声明时,要添加SetLastError=true;如:

1 [DllImport("sensapi.dll", SetLastError = true)]2 private static extern bool IsNetworkAlive(out int connectionDescription);

 

综上,通过IsNetworkAlive可获取当前环境是否已经连接网络。

流程:网络是否连接->是否有无线网连接->获取无线网状态(信号强度)->返回网络状态

1 [DllImport("sensapi.dll", SetLastError = true)] 2 private static extern bool IsNetworkAlive(out int connectionDescription); 3 public NetworkStatus GetNetworkStatusByNetworkAlive() 4 { 5     var networkStatus = NetworkStatus.InternetWithError; 6  7     int flags = 0; 8     var isNetworkAlive = IsNetworkAlive(out flags); 9 10     int errCode = Marshal.GetLastWin32Error();11     if (errCode != 0)12     {13         throw new InvalidOperationException($"通过{nameof(IsNetworkAlive)}非托管DLL,获取网络状态时,遇到异常");14     }15     if (isNetworkAlive)16     {17         // 获取WLAN网络状态18         var wlanStatus = GetWlanStatus();19         if (isNetworkAlive && wlanStatus == NetworkStatus.WifiWithErro)20         {21             networkStatus = NetworkStatus.Internet;22         }23         else24         {25             networkStatus = wlanStatus;26         }27     }28     return networkStatus;29 }

如上,获取网络状态是否连接,建议通过IsNetworkAlive函数获取。那么IsNetworkAlive是否准确呢?

答案是否!

案例:

  1. 电脑配置了虚拟机连接--断网后,IsNetworkAlive返回的是有网true !
  2. 在某些情况下,光纤等坏了,上不了网络,但是走TCP协议可以聊微信QQ--IsNetworkAlive返回的是有网true !

 

所以:IsNetworkAlive函数,建议可以用来,减少断网后请求服务器的次数,或者对有网情况下网络的判断(暂时没发现有网时判断出错的问题)

或者也可以直接使用ping

1     using (var ping = new Ping())2     {3         //ping给定的host,超时时间为1s4         var reply = ping.Send(host, 1000);5         var pingResult= reply != null && reply.Status == IPStatus.Success;6     }

 

网络状态枚举值:

暂时只定义了有线网和无线网的状态 

1     ///  2     /// 网络状态 3     ///  4     public enum NetworkStatus 5     { 6         Internet, 7         InternetWithError, 8         WifiWithErro, 9         WifiWithOneBar,10         WifiWithTwoBars,11         WifiWithThreeBars,12         WifiWithFourBars,13     }

那么,具体是否有线/还是无线网络,如何判断?见下文~

 

获取无线网络的信号强度

获取WLAN的名称与信号强度

无线网的信息,可以通过第三方开源来获取。

ManagedWifi.Dll也可以从我的云盘下载: 密码:2d2o

下载后引用到项目中

1. WlanClient wlanClient = new WlanClient();

2. 循环foreach(WlanClient.WlanInterface wlanIface in wlanClient.Interfaces)

3. Wlan.WlanAvailableNetwork[] networks = wlanIface.GetAvailableNetworkList(0);

值得注意的是,

  • WlanClient只在有网卡的系统中能初始化--所以如果WlanClient不能初始化,且IsNetworkAlive返回true,则意味着当前是有线连接网线
  • WlanInterfacer的GetAvailableNetworkList方法,获取的是附近wifi热点列表,和任务栏下热点列表的顺序无关。
  • WlanAvailableNetwork的wlanSignalQuality信号强度,100以内,如要转换成信号格数,需要整除25
  • profileName,对已连接的热点profileName显示完整,未连接的热点profileName为empty.

获取无线网连接状态:

1 private NetworkStatus GetWlanStatus() 2 { 3     var wlanStatus = NetworkStatus.WifiWithErro; 4     try 5     { 6         WlanClient wlanClient = new WlanClient(); 7  8         foreach (WlanClient.WlanInterface wlanIface in wlanClient.Interfaces) 9         {10             if (wlanIface.InterfaceState == Wlan.WlanInterfaceState.Connected && wlanIface.CurrentConnection.isState == Wlan.WlanInterfaceState.Connected)11             {12                 Wlan.WlanAvailableNetwork[] networks = wlanIface.GetAvailableNetworkList(0);13                 foreach (var network in networks)14                 {15                     if (network.profileName == wlanIface.CurrentConnection.profileName16                         && (int)network.flags == (int)(Wlan.WlanAvailableNetworkFlags.Connected | Wlan.WlanAvailableNetworkFlags.HasProfile))17                     {18                         switch (network.wlanSignalQuality / 25)19                         {20                             case 0:21                                 wlanStatus = NetworkStatus.WifiWithOneBar;22                                 break;23                             case 1:24                                 wlanStatus = NetworkStatus.WifiWithTwoBars;25                                 break;26                             case 2:27                                 wlanStatus = NetworkStatus.WifiWithThreeBars;28                                 break;29                             default:30                                 wlanStatus = NetworkStatus.WifiWithFourBars;31                                 break;32                         }33                         break;34                     }35                 }36                 break;37             }38         }39     }40     catch (Exception e)41     {42     }43     return wlanStatus;44 }

 

关键字:网络连接状态NetworkStatus,无线网络强度(格数),ManagedWifi,IsNetworkAlive,GetLastError

作者:
出处:
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
你可能感兴趣的文章
cas系列-cas登出(四)
查看>>
Java练习 SDUT-1149_计算题
查看>>
运行shell脚本的三种方式
查看>>
Java I/O总结
查看>>
学习笔记之scikit-learn
查看>>
用java集合模拟登录和注册功能
查看>>
安装CPqD/ofdissector遭遇的错误
查看>>
C++ 顺序容器
查看>>
Linux下安装ElasticSearch 5 和配置外部访问
查看>>
微信授权登录
查看>>
去除多余样式
查看>>
NuGet Package Explorer使用教程下载
查看>>
还有5个月就NOIP2019了,我干了什么
查看>>
(转)linux下和云端通讯的例程, ubuntu和openwrt下实验成功(二)
查看>>
hdu2707
查看>>
oralce 常用sql
查看>>
POJ 2117 (割点+连通分量)
查看>>
计算树形节点间的距离
查看>>
使用 dep 配置 golang 开发环境
查看>>
处理器管理与进程管理
查看>>