C# 获取电脑的网络连接状态
原文:C# 获取电脑的网络连接状态

判断连网的方法介绍

1. InternetGetConnectedState

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

  (BUG) InternetGetConnectedState API returns false result

  Detecting LAN connection using InternetGetConnectedState API doesn't work

  https://stackoverflow.com/questions/14127810/check-internet-connection-with-internetgetconnectedstate-always-true

  https://bbs.csdn.net/topics/340141699

在看下文之前,可以浏览MSDN:通过InternetGetConnectedState方法对网络状态的获取

如上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)

浏览:MSDN对IsNetworkAlive的详细描述

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

输出值lpdwFlags

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

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

无线网络的判断:lpdwFlags对是否无线网络,并没有直接的判断。

eg:比如我的电脑环境(有线网络或者wifi网络),获取的flag=1(局域网)

返回值(bool)

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

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

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

参考链接

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

 1     /// <summary>2     /// 通过使用平台调用的最后一个非托管函数返回的错误代码返回调用具有 <see cref="F:System.Runtime.InteropServices.DllImportAttribute.SetLastError" /> 标志设置。  3 /// </summary>  4 /// <returns>最后一个错误代码设置通过调用 Win32 SetLastError 函数。</returns>  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的详细描述信息,可参考https://my.oschina.net/kavensu/blog/264273

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

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

4. 使用Ping函数

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

推荐判断电脑连接网络的方案

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

答案是否!

案例:

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

无网络时,有可能返回有网:lpdwFlags=1 局域网时,如果当前配置了虚拟机连接之类的,本机无法连接网络时,IsNetworkAlive函数还是会返回true。如下:

如果是局域网且IsNetworkAlive返回true,则使用InternetGetConnectedState重新获取网络状态。

 1     //通过IsNetworkAlive方法,来获取电脑的联网状态
 2     [DllImport("sensapi.dll", SetLastError = true)]
 3     private static extern bool IsNetworkAlive(out int connectionDescription);
 4
 5     //通过InternetGetConnectedState方法,来获取电脑的联网状态
 6     [DllImport("winInet.dll")]
 7     private static extern bool InternetGetConnectedState(ref IntPtr dwFlag, int dwReserved);
 8
 9     /// <summary>
10     /// IsNetworkAlive函数输出值1-连接局域网
11     /// </summary>
12     private const int LanNetworkConnectedFlag = 1;
13     /// <summary>
14     /// 网络是否连接
15     /// </summary>
16     public static bool IsConnected
17     {
18         get
19         {
20             var isNetworkConnected = IsNetworkAlive(out int flags);
21             int errCode = Marshal.GetLastWin32Error();
22             if (errCode != 0)
23             {
24                 Console.WriteLine($"通过{nameof(IsNetworkAlive)}非托管DLL函数,获取网络状态时,遇到异常!");
25             }
26
27             //IsNetworkAlive检测到是局域网连上网络,则使用InternetGetConnectedState重新确认是否有网
28             if (isNetworkConnected && flags == LanNetworkConnectedFlag)
29             {
30                 var dwFlag = new IntPtr();
31                 isNetworkConnected = InternetGetConnectedState(ref dwFlag, 0);
32                 errCode = Marshal.GetLastWin32Error();
33                 if (errCode != 0)
34                 {
35                     Console.WriteLine($"通过{nameof(InternetGetConnectedState)}非托管DLL函数,获取网络状态时,遇到异常!");
36                 }
37             }
38
39             return isNetworkConnected;
40         }
41     }

获取系统的网络状态与无线网的信号强度(格数)

posted on 2018-08-03 00:08 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/9410977.html

C# 获取电脑的网络连接状态相关推荐

  1. Android系统信息获取 之六:网络连接状态信息获取

    Android系统可以通过WIFI和移动网络来连接互联网,系统网络连接状态是通过ConnectivityManager 类来获取的.关键代码如下: [java] view plaincopy Conn ...

  2. Windows Phone 8 获取与监听网络连接状态

    现在的只能手机对网络的依赖程度都很高,尤其是新闻.微博.音乐.视频.VOIP通话.游戏等 事实性高的信息类应用,但是目前国内的信息费仍然高居不下,更多的用户只有在 WIFI 的环境下才愿意进行大数据量 ...

  3. iOS获取当前网络连接状态WiFi、5G、4G、3G、2G

    iOS获取网络连接状态 通过AFNetworking获取的网络状态只有未知.无网络连接.手机自带网络.WIFI,需求是需要准确的定位到是WiFi.5G.4G.3G.2G,所以AFNetworking并 ...

  4. zabbix监控网络连接状态

    目录 一.环境准备 二.网络连接状态介绍 三.自定义监控key 四.给主机添加监控项 一.环境准备 1.搭建zabbix基础环境 zabbix基础环境部署参照:zabbix基础环境部署_桂安俊@kyl ...

  5. Android编程获取网络连接状态及调用网络配置界面

    获取网络连接状态 随着3G和Wifi的推广,越来越多的Android应用程序需要调用网络资源,检测网络连接状态也就成为网络应用程序所必备的功能. Android平台提供了ConnectivityMan ...

  6. Android编程获取网络连接状态(3G/Wifi)及调用网络配置界面

    http://www.mobiletuts.me 获取网络连接状态 随着3G和Wifi的推广,越来越多的Android应用程序需要调用网络资源,检测网络连接状态也就成为网络应用程序所必备的功能. An ...

  7. android编程获取网络和wifi状态及调用网络设置界面,Android编程获取网络连接状态(3G/Wifi)及调用网络配置界面 - Android平台开发技术 - 博客园...

    获取网络连接状态 随着3G和Wifi的推广,越来越多的Android应用程序需要调用网络资源,检测网络连接状态也就成为网络应用程序所必备的功能. Android平台提供了ConnectivityMan ...

  8. Android编程 获取网络连接状态 及调用网络配置界面

    获取网络连接状态 随着3G和Wifi的推广,越来越多的Android应用程序需要调用网络资源,检测网络连接状态也就成为网络应用程序所必备的功能. Android平台提供了ConnectivityMan ...

  9. 安卓网络连接全解:包括网络连接状态的监听、网络数据使用状态的监听、获取当前网络连接情况、启动wifi、获取当前连接wifi的网络情况、扫描wifi热点

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓网络连接情况全解:包括网络连接状态的监听.网络数据使用状态的监听.获取当前网络连接情况.启动wifi.获取当前连接wifi的网络情况.扫描wifi ...

最新文章

  1. 面了小 100 人,90% 都背了面试题......
  2. 本年扩增子、宏基因组课程报名已满,想要学最早等明年
  3. 科学养猪的真正奥义,培养拯救人类的医学英雄
  4. BeautifulSoup解析库详解
  5. cocos2dx游戏解决方案
  6. cli parser_Java命令行界面(第27部分):cli-parser
  7. 规模大的优化mysql_十大MySQL优化技巧
  8. java可视化编程教程_JAVA可视化编程——SWING
  9. MATLAB生成M序列和Gold序列
  10. 中兴新支点操作系统_中兴新支点操作系统下载
  11. 干货-Google支付后台验证操作流程【业务后台-GP后台流程】
  12. PIC18f46j50单片机里SPI部分的一点程序
  13. Java Game Resource
  14. OpenCPU入门基础
  15. 怎么样用matlab做视频,MATLAB:使用writeVideo制作视频
  16. Android 适配Dark Theme(暗黑模式),看完跪了
  17. 推荐12个优质技术公众号!
  18. 多线程有几种实现方法,同步有几种实现方法
  19. 为什么有的人说话一定要带手势?生物学基础找到了
  20. 城市大脑一网统管建设解决方案 城市大脑一网统管及领导驾驶舱系统建设解决方案

热门文章

  1. iframe 父页面与子页面之间的方法的相互调用
  2. 运维经验分享(六)-- 深究crontab不能正确执行Shell脚本的问题(二)
  3. 石大ACM2587解题报告
  4. 【转】JS回调函数--简单易懂有实例
  5. 基于AngularJS的Onsen UI --Onsen UI学习笔记
  6. AQS分析(AbstractQueuedSynchronizer)(三)
  7. BZOJ 2111 [ZJOI2010]Perm 排列计数:Tree dp + Lucas定理
  8. JavaScript 对象属性作实参以及实参对象的callee属性
  9. oracle经典书籍推荐
  10. RecycleView Layout 详解