Qual è il modo migliore per determinare se è disponibile una connessione di rete?
Qual è il modo migliore per determinare se è disponibile una connessione di rete?
Risposte:
È possibile verificare una connessione di rete in .NET 2.0 utilizzando GetIsNetworkAvailable():
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()
Per monitorare le modifiche nell'indirizzo IP o le modifiche nella disponibilità della rete, utilizzare gli eventi della classe NetworkChange :
System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged
NetworkInterface.GetIsNetworkAvailable()è stato molto inaffidabile nella mia applicazione (.NET 4.5, Windows 10), soprattutto se eseguito in una macchina virtuale. La gestione degli eventi da NetworkAvailabilityChangedè stata affidabile.
La risposta contrassegnata va bene al 100%, tuttavia, ci sono alcuni casi in cui il metodo standard viene ingannato dalle carte virtuali (scatola virtuale, ...). È anche spesso desiderabile scartare alcune interfacce di rete in base alla loro velocità (porte seriali, modem, ...).
Ecco un pezzo di codice che controlla questi casi:
/// <summary>
/// Indicates whether any network connection is available
/// Filter connections below a specified speed, as well as virtual network cards.
/// </summary>
/// <returns>
/// <c>true</c> if a network connection is available; otherwise, <c>false</c>.
/// </returns>
public static bool IsNetworkAvailable()
{
return IsNetworkAvailable(0);
}
/// <summary>
/// Indicates whether any network connection is available.
/// Filter connections below a specified speed, as well as virtual network cards.
/// </summary>
/// <param name="minimumSpeed">The minimum speed required. Passing 0 will not filter connection using speed.</param>
/// <returns>
/// <c>true</c> if a network connection is available; otherwise, <c>false</c>.
/// </returns>
public static bool IsNetworkAvailable(long minimumSpeed)
{
if (!NetworkInterface.GetIsNetworkAvailable())
return false;
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
// discard because of standard reasons
if ((ni.OperationalStatus != OperationalStatus.Up) ||
(ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) ||
(ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel))
continue;
// this allow to filter modems, serial, etc.
// I use 10000000 as a minimum speed for most cases
if (ni.Speed < minimumSpeed)
continue;
// discard virtual cards (virtual box, virtual pc, etc.)
if ((ni.Description.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
// discard "Microsoft Loopback Adapter", it will not show as NetworkInterfaceType.Loopback but as Ethernet Card.
if (ni.Description.Equals("Microsoft Loopback Adapter", StringComparison.OrdinalIgnoreCase))
continue;
return true;
}
return false;
}
Microsoft windows vista e 7 utilizzano la tecnica NCSI (Network Connectivity Status Indicator):
Chiama questo metodo per controllare la connessione di rete.
public static bool IsConnectedToInternet()
{
bool returnValue = false;
try
{
int Desc;
returnValue = Utility.InternetGetConnectedState(out Desc, 0);
}
catch
{
returnValue = false;
}
return returnValue;
}
Mettilo sotto la riga di codice.
[DllImport("wininet.dll")]
public extern static bool InternetGetConnectedState(out int Description, int ReservedValue);