88bf必发娱乐 3

88bf必发娱乐C# 获取电脑的网络连接状态

 判断连网的方法介绍

然后就可以调用函数判断系统是否连接到INTERNET

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

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

答案是否!

案例:

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

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

88bf必发娱乐 1

 
所以,如果是局域网且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     }

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

 

返回值(bool)

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

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

还有要定义三个常量:

 2. IsNetworkAlive

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

浏览:MSDN对IsNetworkAlive的详细描述

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

Delphi中没有对这个函数进行声明,所以我们要自己声明,请把下面的代码加入到当前窗体或者单元的
声明全局变量的地方也就是第一个var下面。

 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     }

该函数返回TRUE说明本地系统没有连接到INTERNET。
附:
大多数装有IE或OFFICE97的系统都有此DLL可供调用。
InetIsOffline
BOOL InetIsOffline(
DWORD dwFlags,
);

输出值lpdwFlags

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

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

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

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

88bf必发娱乐 2

 

procedure ShowNetWorkState();
var
falg:integer;
Bos:boolean;
begin
  Bos:=false;
  IsNetworkAlive(falg);
  case falgof
   NETWORK_ALIVE_LAN:
     begin
       Showmessage(‘通过局域网上网。’);
       Bos:=true;
     end;
   NETWORK_ALIVE_WAN:
     begin
     Showmessage(‘通过广域网上网。’);
       Bos:=true;
     end;
   NETWORK_ALIVE_AOL:
     begin
       Showmessage(‘联上美国的网络。’);  //仅对98/95有效所以一般不用判断NETWORK_ALIVE_AOL
       Bos:=true;
     end;
    else Showmessage(‘没有联网。’);
  end;  //case
if Bos then Showmessage(‘你现在是联网状态!’)
  elseShowmessage(‘你现在是离线状态!’);
end;

 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方法对网络状态的获取.aspx)

如上InternetGetConnectedState方法介绍中

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

    bool InternetGetConnectedState( out LPDWORD lpdwFlags, int dwReversed);

88bf必发娱乐 3

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

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

在DELPHI中引用wininet这个单元就可以直接使用 InternetGetConnectedState函数了,下面给出一个判断当前网络连接状态的函数,在注释中会一一解释它的一些相关返回值的含义。

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);

一、InternetGetConnectedState

Const NETWORK_ALIVE_LAN
=1;  //通过局域网上网
ConstNETWORK_ALIVE_WAN =
2;  //通过广域网上网
ConstNETWORK_ALIVE_AOL =
4;  //仅对98/95有效判断是否联上美国网络

functionConnectionKind :boolean;
var flags: dword;
begin
  Result :=InternetGetConnectedState(@flags, 0);
    if Result then
     begin
       if (flags
andINTERNET_CONNECTION_MODEM) =INTERNET_CONNECTION_MODEM then showmessage(‘在线:拨号上网’);
       if (flags and
INTERNET_CONNECTION_LAN)= INTERNET_CONNECTION_LAN then showmessage(‘在线:通过局域网’);
       if (flags
andINTERNET_CONNECTION_PROXY) =INTERNET_CONNECTION_PROXY then showmessage(‘在线:代理’);
       if (flags
andINTERNET_CONNECTION_MODEM_BUSY)=INTERNET_CONNECTION_MODEM_BUSYthen showmessage(‘MODEM被其他非INTERNET连接占用’);
     end; //if
88bf必发娱乐,end;//function

下面再介绍一个方法可以判断网络是否连通的。

过程结束 下面说下各各返回值的意思:
INTERNET_CONNECTION_MODEM: //现在是通过拨号方式上网的
INTERNET_CONNECTION_LAN:  //现在是通过局域网上网的
INTERNET_CONNECTION_PROXY: //现在是通过代理上网的
INTERNET_CONNECTION_MODEM_BUSY: //现在MODEM被其他非INTERNET连接占用(离线)

Function IsNetworkAlive(varlpdwFlagsLib:Integer):Integer;stdcall;external’SENSAPI.DLL’;

Delphi中没有对该函数进行声明,所以我们要自己声明,这跟上面的第二种方法的声明是同个道理
函数申明为:
functionInetIsOffline(Flag:
Integer): Boolean;stdcall; external ‘URL.DLL’;

二、IsNetworkAlive

if InetIsOffline(0)then ShowMessage(‘没有连接到网络’)
else ShowMessage(‘已经连接到网络’);

下面还是给出一个过程来判断当前网络的状态,这次是一个过程

 

uses wininet;//这个已经说了必须引用它才可以使用InternetGetConnectedState函数

三、URL.DLL中的InetIsOffline函数。

判断网络的是否连接或者连接方式,比较重要的一点就是是不是即时判断,如果你明明无连接,判断出来却说你有,连接上了,却说你还未连接,下面要介绍的两个方法中InternetGetConnectedState就是不怎么够即时的API函数,而第二个使用的是IsNetworkAlive这个API函数,这个没有InternetGetConnectedState的那种问题,但是可能需要安装SDK,也就是.Net框架。

以上就是通过使用InternetGetConnectedState函数实现的判断网络状态的方法

[hr]