Moh*_*nde 224 .net c# internet-connection
在.NET中检查Internet连接的最快,最有效的方法是什么?
Cha*_*ion 271
这样的事情应该有效.
public static bool CheckForInternetConnection()
{
try
{
using (var client = new WebClient())
using (client.OpenRead("http://google.com/generate_204"))
return true;
}
catch
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
Leo*_*Leo 77
绝对没有办法可以可靠地检查是否有互联网连接(我认为你的意思是访问互联网).
但是,您可以请求几乎从不离线的资源,例如ping google.com或类似的东西.我认为这会很有效率.
try {
Ping myPing = new Ping();
String host = "google.com";
byte[] buffer = new byte[32];
int timeout = 1000;
PingOptions pingOptions = new PingOptions();
PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
return (reply.Status == IPStatus.Success);
}
catch (Exception) {
return false;
}
Run Code Online (Sandbox Code Playgroud)
dba*_*ett 40
而不是检查,只需执行操作(Web请求,邮件,ftp等),并为失败请求做好准备,即使您的检查成功,您也必须这样做.
考虑以下:
1 - check, and it is OK
2 - start to perform action
3 - network goes down
4 - action fails
5 - lot of good your check did
Run Code Online (Sandbox Code Playgroud)
如果网络中断,您的操作将像ping一样快速失败等.
1 - start to perform action
2 - if the net is down(or goes down) the action will fail
Run Code Online (Sandbox Code Playgroud)
Kam*_*hid 28
NetworkInterface.GetIsNetworkAvailable
非常不可靠.只是有一些VMware或其他LAN连接,它将返回错误的结果.另外关于Dns.GetHostEntry
方法我只关心测试URL是否可能在我的应用程序要部署的环境中被阻止.
所以我发现的另一种方法是使用InternetGetConnectedState
方法.我的代码是
[System.Runtime.InteropServices.DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
public static bool CheckNet()
{
int desc;
return InternetGetConnectedState(out desc, 0);
}
Run Code Online (Sandbox Code Playgroud)
小智 13
通过ping Google来测试互联网连接:
new Ping().Send("www.google.com.mx").Status == IPStatus.Success
Run Code Online (Sandbox Code Playgroud)
PJR*_*bot 11
我不同意那些表示:"在执行任务之前检查连接的重点是什么,因为检查后连接可能会丢失".当然,我们作为开发人员所承担的许多编程任务存在一定程度的不确定性,但将不确定性降低到接受程度是挑战的一部分.
我最近遇到了这个问题,制作了一个包含链接到在线磁贴服务器的映射功能的应用程序.在注意到缺乏互联网连接的情况下,将禁用此功能.
此页面上的一些响应非常好,但是确实导致很多性能问题,例如挂起,主要是在没有连接的情况下.
以下是我最终使用的解决方案,借助其中一些答案和我的同事:
// Insert this where check is required, in my case program start
ThreadPool.QueueUserWorkItem(CheckInternetConnectivity);
}
void CheckInternetConnectivity(object state)
{
if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
using (WebClient webClient = new WebClient())
{
webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
webClient.Proxy = null;
webClient.OpenReadCompleted += webClient_OpenReadCompleted;
webClient.OpenReadAsync(new Uri("<url of choice here>"));
}
}
}
volatile bool internetAvailable = false; // boolean used elsewhere in code
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
internetAvailable = true;
Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
// UI changes made here
}));
}
}
Run Code Online (Sandbox Code Playgroud)
Jin*_*lye 10
Ping google.com 引入了 DNS 解析依赖项。Ping 8.8.8.8 很好,但 Google 离我很远。我需要做的就是 ping 互联网上离我最近的东西。
我可以使用 Ping 的 TTL 功能来 ping 跳 #1,然后跳 #2,等等,直到我收到来自可路由地址上的某些内容的回复;如果该节点位于可路由地址上,则它位于 Internet 上。对于我们大多数人来说,第 1 跳将是我们的本地网关/路由器,第 2 跳将是光纤连接另一端的第一个点或其他任何地方。
这段代码对我有用,并且比该线程中的其他一些建议响应更快,因为它正在 ping 互联网上离我最近的任何东西。
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;
public static async Task<bool> IsConnectedToInternetAsync()
{
const int maxHops = 30;
const string someFarAwayIpAddress = "8.8.8.8";
// Keep pinging further along the line from here to google
// until we find a response that is from a routable address
for (int ttl = 1; ttl <= maxHops; ttl++)
{
var options = new PingOptions(ttl, true);
byte[] buffer = new byte[32];
PingReply reply;
try
{
using (var pinger = new Ping())
{
reply = await pinger.SendPingAsync(someFarAwayIpAddress, 10000, buffer, options);
}
}
catch (PingException pingex)
{
Debug.Print($"Ping exception (probably due to no network connection or recent change in network conditions), hence not connected to internet. Message: {pingex.Message}");
return false;
}
string address = reply.Address?.ToString() ?? null;
Debug.Print($"Hop #{ttl} is {address}, {reply.Status}");
if (reply.Status != IPStatus.TtlExpired && reply.Status != IPStatus.Success)
{
Debug.Print($"Hop #{ttl} is {reply.Status}, hence we are not connected.");
return false;
}
if (isRoutableAddress(reply.Address))
{
Debug.Print("That's routable, so we must be connected to the internet.");
return true;
}
}
return false;
}
private static bool IsRoutableAddress(IPAddress addr)
{
if (addr == null)
{
return false;
}
else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
{
return !addr.IsIPv6LinkLocal && !addr.IsIPv6SiteLocal;
}
else // IPv4
{
byte[] bytes = addr.GetAddressBytes();
if (bytes[0] == 10)
{ // Class A network
return false;
}
else if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31)
{ // Class B network
return false;
}
else if (bytes[0] == 192 && bytes[1] == 168)
{ // Class C network
return false;
}
else
{ // None of the above, so must be routable
return true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Hac*_*Man 10
我已经看到上面列出的所有选项,唯一可行的选项来检查互联网是否可用是"Ping"选项.导入 [DllImport("Wininet.dll")]
和/ System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
或NetworkInterface
该类的任何其他变体 在检测网络的可用性时不能很好地工作.这些方法仅检查网络电缆是否插入.
"Ping选项"
if
(连接可用)返回 true
if
(连接不可用且插入网络电缆)返回 false
if
(未插入网络电缆) Throws an exception
NetworkInterface
if
(互联网可用)退货 True
if
(Internet不可用并且已插入网络电缆)返回 True
if
(未插入网络电缆)返回 false
[DllImport("Wininet.dll")]
if
(互联网可用)退货 True
if
(Internet不可用并且已插入网络电缆)返回 True
if
(未插入网络电缆)返回 false
因此,如果[DllImport("Wininet.dll")]
和 NetworkInterface
无法知道互联网连接是否可用.
小智 8
没有解决在检查和运行代码之间网络崩溃的问题,但是相当可靠
public static bool IsAvailableNetworkActive()
{
// only recognizes changes related to Internet adapters
if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
// however, this will include all adapters -- filter by opstatus and activity
NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
return (from face in interfaces
where face.OperationalStatus == OperationalStatus.Up
where (face.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && (face.NetworkInterfaceType != NetworkInterfaceType.Loopback)
select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
下面是它在 Android 中的实现方式。
作为概念证明,我将此代码翻译为 C#:
var request = (HttpWebRequest)WebRequest.Create("http://g.cn/generate_204");
request.UserAgent = "Android";
request.KeepAlive = false;
request.Timeout = 1500;
using (var response = (HttpWebResponse)request.GetResponse())
{
if (response.ContentLength == 0 && response.StatusCode == HttpStatusCode.NoContent)
{
//Connection to internet available
}
else
{
//Connection to internet not available
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
介绍
在某些情况下,您需要在 Windows 应用程序中使用 C# 代码检查互联网是否可用。可能是在 Windows 窗体中使用互联网下载或上传文件,或者从远程位置的数据库获取一些数据,在这些情况下,必须进行互联网检查。
有一些方法可以使用 C# 从代码隐藏中检查互联网可用性。这里解释了所有这些方法,包括它们的局限性。
'wininet' API 可用于检查本地系统是否具有活动的互联网连接。用于此目的的命名空间是“System.Runtime.InteropServices”,并使用 DllImport 导入 dll“wininet.dll”。之后,创建一个带有 extern static 的布尔变量,其函数名称为 InternetGetConnectedState,并带有两个参数 description 和 returnedValue,如示例中所示。
注意:extern 修饰符用于声明外部实现的方法。当您使用 Interop 服务调用非托管代码时,extern 修饰符的常见用途是与 DllImport 属性一起使用。在这种情况下,该方法也必须声明为静态的。
接下来创建一个名为“IsInternetAvailable”作为布尔值的方法。该方法将使用上述函数返回本地系统的互联网状态
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int description, int reservedValue);
public static bool IsInternetAvailable()
{
try
{
int description;
return InternetGetConnectedState(out description, 0);
}
catch (Exception ex)
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
以下示例使用 GetIsNetworkAvailable 方法来确定网络连接是否可用。
if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
System.Windows.MessageBox.Show("This computer is connected to the internet");
}
else
{
System.Windows.MessageBox.Show("This computer is not connected to the internet");
}
Run Code Online (Sandbox Code Playgroud)
备注(根据 MSDN):如果任何网络接口标记为“启动”并且不是环回或隧道接口,则认为网络连接可用。
在许多情况下,设备或计算机未连接到有用的网络,但仍被视为可用,并且 GetIsNetworkAvailable 将返回 true。例如,如果运行应用程序的设备连接到需要代理的无线网络,但未设置代理,则 GetIsNetworkAvailable 将返回 true。GetIsNetworkAvailable 返回 true 的另一个示例是,如果应用程序正在连接到集线器或路由器的计算机上运行,而集线器或路由器已丢失上游连接。
Ping 和 PingReply 类允许应用程序通过从主机获取回复来确定是否可以通过网络访问远程计算机。这些类在 System.Net.NetworkInformation 命名空间中可用。以下示例显示如何 ping 主机。
protected bool CheckConnectivity(string ipAddress)
{
bool connectionExists = false;
try
{
System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingOptions options = new System.Net.NetworkInformation.PingOptions();
options.DontFragment = true;
if (!string.IsNullOrEmpty(ipAddress))
{
System.Net.NetworkInformation.PingReply reply = pingSender.Send(ipAddress);
connectionExists = reply.Status ==
System.Net.NetworkInformation.IPStatus.Success ? true : false;
}
}
catch (PingException ex)
{
Logger.LogException(ex.Message, ex);
}
return connectionExists;
}
Run Code Online (Sandbox Code Playgroud)
备注(根据 MSDN):应用程序使用 Ping 类来检测远程计算机是否可访问。网络拓扑可以决定 Ping 是否可以成功联系远程主机。代理、网络地址转换 (NAT) 设备或防火墙的存在和配置可能会阻止 Ping 成功。Ping 成功仅表明网络上可以到达远程主机;不保证远程主机上存在更高级别的服务(例如 Web 服务器)。
欢迎提出意见/建议。快乐编码......!
归档时间: |
|
查看次数: |
211076 次 |
最近记录: |