如何在我的应用程序中不断检查互联网连接并在连接不可用时做出响应?
目前我正在使用:
while(true) {
if(HasConnection()) {
//doSomething..
}
//stop app by 1sec
}
但它似乎相当不雅。
如何在我的应用程序中不断检查互联网连接并在连接不可用时做出响应?
目前我正在使用:
while(true) {
if(HasConnection()) {
//doSomething..
}
//stop app by 1sec
}
但它似乎相当不雅。
超级用户对此问题的公认答案描述了 Windows 确定其是否具有网络访问权限的方式。您可以使用类似的方法,但我会在您的应用程序启动时生成一个单独的线程,负责进行检查。让单独的线程以您认为最好的方式执行检查,并在连接状态发生变化时引发事件。
使用以下代码:
public static class LocalSystemConnection
{
[DllImport("wininet.dll", SetLastError=true, CallingConvention = CallingConvention.ThisCall)]
extern static bool InternetGetConnectedState(out ConnectionStates lpdwFlags, long dwReserved);
/// <summary>
/// Retrieves the connected state of the local system.
/// </summary>
/// <param name="connectionStates">A <see cref="ConnectionStates"/> value that receives the connection description.</param>
/// <returns>
/// A return value of true indicates that either the modem connection is active, or a LAN connection is active and a proxy is properly configured for the LAN.
/// A return value of false indicates that neither the modem nor the LAN is connected.
/// If false is returned, the <see cref="ConnectionStates.Configured"/> flag may be set to indicate that autodial is configured to "always dial" but is not currently active.
/// If autodial is not configured, the function returns false.
/// </returns>
public static bool IsConnectedToInternet(out ConnectionStates connectionStates)
{
connectionStates = ConnectionStates.Unknown;
return InternetGetConnectedState(out connectionStates, 0);
}
/// <summary>
/// Retrieves the connected state of the local system.
/// </summary>
/// <returns>
/// A return value of true indicates that either the modem connection is active, or a LAN connection is active and a proxy is properly configured for the LAN.
/// A return value of false indicates that neither the modem nor the LAN is connected.
/// If false is returned, the <see cref="ConnectionStates.Configured"/> flag may be set to indicate that autodial is configured to "always dial" but is not currently active.
/// If autodial is not configured, the function returns false.
/// </returns>
public static bool IsConnectedToInternet()
{
ConnectionStates state = ConnectionStates.Unknown;
return IsConnectedToInternet(out state);
}
}
[Flags]
public enum ConnectionStates
{
/// <summary>
/// Unknown state.
/// </summary>
Unknown = 0,
/// <summary>
/// Local system uses a modem to connect to the Internet.
/// </summary>
Modem = 0x1,
/// <summary>
/// Local system uses a local area network to connect to the Internet.
/// </summary>
LAN = 0x2,
/// <summary>
/// Local system uses a proxy server to connect to the Internet.
/// </summary>
Proxy = 0x4,
/// <summary>
/// Local system has RAS (Remote Access Services) installed.
/// </summary>
RasInstalled = 0x10,
/// <summary>
/// Local system is in offline mode.
/// </summary>
Offline = 0x20,
/// <summary>
/// Local system has a valid connection to the Internet, but it might or might not be currently connected.
/// </summary>
Configured = 0x40,
}
您正在寻找NetworkAvailabilityChanged
活动。
要检查互联网连接,您可以ping一个可靠的网站,例如 Google.com。
请注意,不可能在 Internet 连接的每次更改(例如 ISP 中断)时都收到通知。
如果您只需要知道是否至少有一个连接可用,您可以试试这个:
InternetGetConnectedStateEx()
http://msdn.microsoft.com/en-us/library/aa384705%28v=vs.85%29.aspx
如果您想连续检查,请使用计时器
private Timer timer1;
public void InitTimer()
{
timer1 = new Timer();
timer1.Tick += new EventHandler(timerEvent);
timer1.Interval = 2000; // in miliseconds
timer1.Start();
}
private void timerEvent(object sender, EventArgs e)
{
DoSomeThingWithInternet();
}
private void DoSomeThingWithInternet()
{
if (isConnected())
{
// inform user that "you're connected to internet"
}
else
{
// inform user that "you're not connected to internet"
}
}
public static bool isConnected()
{
try
{
using (var client = new WebClient())
using (client.OpenRead("http://clients3.google.com/generate_204"))
{
return true;
}
}
catch
{
return false;
}
}
我知道这是一个老问题,但这对我很有用。
System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
private async void NetworkChange_NetworkAvailabilityChanged(object sender, System.Net.NetworkInformation.NetworkAvailabilityEventArgs e)
{
//code to execute...
}
我将事件订阅给一个侦听器,它会不断检查连接。这您可以添加一个 If 语句,例如:
if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
//Send Ping...
}
else
{
//other code....
}
您可以通过 ping 某些网站来测试 Internet 连接,例如:
public bool IsConnectedToInternet
{
try
{
using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
{
string address = @"http://www.google.com";// System.Net.NetworkInformation.PingReply pingReplay = ping.Send(address);//you can specify timeout.
if (pingReplay.Status == System.Net.NetworkInformation.IPStatus.Success)
{
return true;
}
}
}
catch
{
#if DEBUG
System.Diagnostics.Debugger.Break();
#endif//DEBUG
}
return false;
}
您如何知道您是否有 Internet 连接?您可以将数据包路由到附近的路由器就足够了吗?也许机器只有一个网卡,一个网关,也许网关的连接断开了,但机器仍然可以路由到网关和本地网络?
也许这台机器有一个 NIC 和十几个网关;也许他们一直来来去去,但其中一个总是起来?
如果机器有多个 NIC,但只有一个网关怎么办?也许它可以路由到 Internet 的某个子集,但仍然可以很好地连接到未连接到 Internet 的本地网络?
如果机器有多个 NIC、多个网关,但出于管理策略的原因,仍然只有部分 Internet 是可路由的,该怎么办?
您真的只关心客户端是否连接到您的服务器吗?
数据包之间什么样的延迟是可以接受的?(30ms 很好,300ms 正在突破人类的耐力极限,3000ms 是无法忍受的长时间,960000ms 是连接太阳能探测器所需的时间。)什么样的丢包是可以接受的?
你真正想要衡量的是什么?
这将是一个开始,但正如 sarnold 所提到的,您需要考虑很多事情
使用NetworkChange.NetworkAvailabilityChanged
是最具误导性的答案。它检查网络可用性变化而不是互联网连接变化。
我们可以使用Windows NLM API
.
using System;
using System.Runtime.InteropServices.ComTypes;
using NETWORKLIST;
namespace Components.Network.Helpers
{
public class InternetConnectionChecker : INetworkListManagerEvents, IDisposable
{
private int _cookie;
private IConnectionPoint _connectionPoint;
private readonly INetworkListManager _networkListManager;
public InternetConnectionChecker()
{
_networkListManager = new NetworkListManager();
}
public bool IsConnected()
{
return _networkListManager.IsConnectedToInternet;
}
public void StartMonitoringConnection()
{
try
{
var container = _networkListManager as IConnectionPointContainer;
if (container == null)
throw new Exception("connection container is null");
var riid = typeof(INetworkListManagerEvents).GUID;
container.FindConnectionPoint(ref riid, out _connectionPoint);
_connectionPoint.Advise(this, out _cookie);
}
catch (Exception e)
{
}
}
public void ConnectivityChanged(NLM_CONNECTIVITY newConnectivity)
{
if (_networkListManager.IsConnectedToInternet)
{
// do something based on internet connectivity
}
}
public void Dispose()
{
_connectionPoint.Unadvise(_cookie);
}
}
}
此代码将为您挽救生命.. 它不仅检查真正的互联网连接,而且还处理异常并在控制台窗口上显示...每 2 秒后
using System;
using System.Net;
using System.Threading;
using System.Net.Http;
bool check() //Checking for Internet Connection
{
while (true)
{
try
{ var i = new Ping().Send("www.google.com").Status;
if (i == IPStatus.Success)
{ Console.WriteLine("connected");
return true;
}
else { return false; }
}
catch (Exception)
{
Console.WriteLine("Not Connected");
Thread.Sleep(2000);
continue;
}
}
};
check();