Как определить работу интернет-соединения в С#?
У меня есть код С#, который в основном загружает файл через FTP-протокол (используя FtpWebRequest
). Я бы хотел, однако, сначала определить, есть ли работающее интернет-соединение, прежде чем пытаться загрузить файл (поскольку, если нет, нет смысла пытаться, программное обеспечение должно просто поспать какое-то время и снова проверить).
Есть ли простой способ сделать это, или я просто пытаюсь загрузить файл, и в случае неудачи просто повторите попытку, предполагая, что сетевое соединение было недоступно?
Ответы
Ответ 1
Просто используйте обычную функцию
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()
которые возвращают значение true, если соединение установлено.
Из MSDN:
Сетевое соединение считается доступным, если какой-либо сетевой интерфейс помечен как "вверх" и не является интерфейсом loopback или туннеля.
Помните, что подключение не все, вы можете подключиться к локальной сети, и маршрутизатор, к примеру, не подключен к Интернету. Чтобы действительно узнать, подключены ли вы к Интернету, попробуйте Ping класс.
Ответ 2
Существует событие "изменение сети", которое срабатывает при изменении состояния "вверх" сетевого подключения на интерфейсе, который не является туннелем или шлейфом.
Вы можете прочитать состояние всех сетевых адаптеров в системе при запуске, сохранить текущее значение "сеть доступна", затем прослушать это событие и изменить переменную состояния сети, когда это событие срабатывает. Это также похоже на то, что он будет обрабатывать коммутируемые и ISDN-соединения.
Предусмотрены другие факторы, которые необходимо учитывать, например, сетевой адаптер подключен к маршрутизатору (и работает), но подключение к Интернету на маршрутизаторе не работает или удаленный хост не отвечает, но это, по крайней мере, предотвратит вы пытаетесь установить соединение, которое не будет работать, если с ним не будет сетевого подключения (например, соединение VPN или ISDN не работает.)
Это консольное приложение С# - запустите его, затем отключите или отключите сетевое соединение: -)
class Program
{
static bool networkIsAvailable = false;
static void Main(string[] args)
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface nic in nics)
{
if (
(nic.NetworkInterfaceType != NetworkInterfaceType.Loopback && nic.NetworkInterfaceType != NetworkInterfaceType.Tunnel) &&
nic.OperationalStatus == OperationalStatus.Up)
{
networkIsAvailable = true;
}
}
Console.Write("Network availability: ");
Console.WriteLine(networkIsAvailable);
NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
Console.ReadLine();
}
static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
networkIsAvailable = e.IsAvailable;
Console.Write("Network availability: ");
Console.WriteLine(networkIsAvailable);
}
}
Ответ 3
Я думаю, что наилучшим приближением, которое вы можете использовать, является проверка значения OperationalStatus
в типе NetworkInterface
.
using System.Net.NetworkInformation;
public bool IsNetworkLikelyAvailable() {
return NetworkInterface
.GetAllNetworkInterfaces()
.Any(x => x.OperationalStatus == OperationalStatus.Up);
}
Помните, хотя это приближение. В тот момент, когда этот метод вернется, компьютер может потерять или получить интернет-соединение. IMO Я бы просто пошел прямо к загрузке и обработал ошибку, так как вы не можете доказать, что этого не произойдет.
Ответ 4
Подумайте о ситуации, когда ваш чек возвращается и говорит "соединение есть", и прежде чем вы сможете запустить FTP, соединение падает.
Или, когда соединение падает частично через ваш запрос FTP.
Учитывая, что вы все равно должны кодировать эти ситуации, просто пропустите проверку
Изменить в ответ на комментарии Джейсона
Вы также можете иметь противоположное условие: когда вы проверяете соединение, его нет, но через мгновение появляется их соединение. Итак, что вы теперь делаете - начинаете ли вы возиться с пользователем об отсутствии соединения, даже если он теперь доступен?
В конце дня вы имеете дело с большим количеством ресурсов (ваше сетевое соединение, любые промежуточные маршрутизаторы, хост, его FTP-сервис). Все они могут быть изменены вне вашего контроля (как указано в комментарии Seth), и никакая предварительная проверка не ответит на вопрос "смогу ли я завершить эту загрузку"?
Поскольку OP указывал, что он думает о "отступлении и повторите попытку позже", тогда я считаю уместным сделать все это в фоновом режиме и не раздражать пользователя вообще - если вы не пытались "необоснованное" количество времени без успеха.
Ответ 5
Не можете ли вы использовать Ping Class системы . Net.NetworkInformation Namespace для отправки FTP-сервера перед загрузкой файла?
Ответ 6
Если вам сложно выполнить ping, просто используйте webclient.
public static bool CheckForInternetConnection()
{
try
{
using (var client = new WebClient())
using (var stream = client.OpenRead("http://www.google.com"))
{
return true;
}
}
catch
{
return false;
}
}
или любого другого сайта.
EDIT: вы можете использовать http://www.msftncsi.com/ этот сайт. Это сайт, который запускается только для подключения к Интернету. См. Подробное объяснение реестра о том, как Windows 7 находит подключение к Интернету http://blog.superuser.com/2011/05/16/windows-7-network-awareness/
Ответ 7
просто написал async-функции для этого:
private void myPingCompletedCallback(object sender, PingCompletedEventArgs e)
{
if (e.Cancelled)
return;
if (e.Error != null)
return;
if (e.Reply.Status == IPStatus.Success)
{
//ok connected to internet, do something...
}
}
private void checkInternet()
{
Ping myPing = new Ping();
myPing.PingCompleted += new PingCompletedEventHandler(myPingCompletedCallback);
try
{
myPing.SendAsync("google.com", 3000 /*3 secs timeout*/, new byte[32], new PingOptions(64, true));
}
catch
{
}
}