Обнаружение простоя интернета

Как определить, когда Интернет не используется (нет загрузки / выгрузки) с помощью C#, и начать загрузку, когда он есть?

1 ответ

Если вы ждете момента, когда нет подключений... вы должны знать, что существует множество подключений, даже если вы думаете, что не используете Интернет.

Попробуйте взглянуть на WireShark и Prcomon (от sysitnerals), чтобы иметь представление.


Неработающий трафик

Примечание: если вы используете.NET на Mac или Linux через Mono, вы должны знать, что этот API плохо переносится на другие операционные системы. Итак, что я описываю здесь, только для Windows.

Если вам нужно иметь представление о трафике, вы можете попробовать использовать System.Net.NetworkInformation.IPGlobalStatistics.

Вы можете сделать это так:

var properties = IPGlobalProperties.GetIPGlobalProperties();
// IPGlobalStatistics for IPv4
var ipv4stat = properties.GetIPv4GlobalStatistics();
// IPGlobalStatistics for IPv6
var ipv6stat = properties.GetIPv6GlobalStatistics();

Из примера на MSDN:

Console.WriteLine("  Forwarding enabled ...................... : {0}", 
    ipstat.ForwardingEnabled);
Console.WriteLine("  Interfaces .............................. : {0}", 
    ipstat.NumberOfInterfaces);
Console.WriteLine("  IP addresses ............................ : {0}", 
    ipstat.NumberOfIPAddresses);
Console.WriteLine("  Routes .................................. : {0}", 
    ipstat.NumberOfRoutes);
Console.WriteLine("  Default TTL ............................. : {0}", 
    ipstat.DefaultTtl);
Console.WriteLine("");    
Console.WriteLine("  Inbound Packet Data:");
Console.WriteLine("      Received ............................ : {0}", 
    ipstat.ReceivedPackets);
Console.WriteLine("      Forwarded ........................... : {0}", 
    ipstat.ReceivedPacketsForwarded);
Console.WriteLine("      Delivered ........................... : {0}", 
    ipstat.ReceivedPacketsDelivered);
Console.WriteLine("      Discarded ........................... : {0}", 
    ipstat.ReceivedPacketsDiscarded);
Console.WriteLine("      Header Errors ....................... : {0}", 
    ipstat.ReceivedPacketsWithHeadersErrors);
Console.WriteLine("      Address Errors ...................... : {0}", 
    ipstat.ReceivedPacketsWithAddressErrors);
Console.WriteLine("      Unknown Protocol Errors ............. : {0}", 
    ipstat.ReceivedPacketsWithUnknownProtocol);
Console.WriteLine("");    
Console.WriteLine("  Outbound Packet Data:");
Console.WriteLine("      Requested ........................... : {0}", 
     ipstat.OutputPacketRequests);
Console.WriteLine("      Discarded ........................... : {0}", 
    ipstat.OutputPacketsDiscarded);
Console.WriteLine("      No Routing Discards ................. : {0}", 
    ipstat.OutputPacketsWithNoRoute);
Console.WriteLine("      Routing Entry Discards .............. : {0}", 
    ipstat.OutputPacketRoutingDiscards);
Console.WriteLine("");    
Console.WriteLine("  Reassembly Data:");
Console.WriteLine("      Reassembly Timeout .................. : {0}", 
    ipstat.PacketReassemblyTimeout);
Console.WriteLine("      Reassemblies Required ............... : {0}", 
    ipstat.PacketReassembliesRequired);
Console.WriteLine("      Packets Reassembled ................. : {0}", 
    ipstat.PacketsReassembled);
Console.WriteLine("      Packets Fragmented .................. : {0}", 
    ipstat.PacketsFragmented);
Console.WriteLine("      Fragment Failures ................... : {0}", 
    ipstat.PacketFragmentFailures);
Console.WriteLine("");

Интернет доступен?

Если вам нужно получить уведомление, когда Интернет доступен, вы можете подписаться на System.Net.NetworkInformation.NetworkChange. NetworkAvailabilityChanged. Таким образом, вы получите уведомление о событии, если Интернет подключен или отключен (не забудьте отписаться).

Пример:

var handler = new NetworkAddressChangedEventHandler
                  (
                      (sender, args) => 
                      {
                          //handle notification
                      }
                  );
System.Net.NetworkInformation.NetworkChange += handler;

// Unsubscribe:
System.Net.NetworkInformation.NetworkChange -= handler;

Возможно, вам будет интересно узнать, какие сетевые адаптеры работают вверх или вниз и сколько трафика у каждого... для этого см. Ниже.


Простой и простой

Давайте определим " холостые ". Я бы сказал, что "простаивает" означает, что Интернет доступен (см. Выше), и если он не использовался в течение определенного количества времени.

Итак, еще одна вещь, которую вам нужно сделать, это вызвать NetworkInterface.GetAllNetworkInterfaces, который даст вам массив System.Net.NetworkInformation.NetworkInterface, для которого вы можете вызвать метод GetIPStatistics, чтобы получить объект IPStatistics для этого конкретного интерфейса netowork. Вы также можете прочитать свойство OperationalStatus, чтобы узнать, включен ли конкретный интерфейс или нет.

Пример:

 NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
 foreach (var adapter in adapters)
 {
      // Is Up, Down, something else?
      Console.WriteLine("   {0} is {1}", adapter.Name, dapter.OperationalStatus);
      var stats = adapter.GetIPStatistics();
      // Read some properties
      Console.WriteLine("       Bytes Recieved: {0}", stats.BytesReceived);
      Console.WriteLine("       Bytes Sent: {0}", stats.BytesSent);
 }

Что вам нужно будет сделать, это сохранить эту информацию так, чтобы вы могли запросить ее, чтобы проверить, изменилась ли она:

// Fields
Dictionary<string, Tuple<long, long>> data
     = new Dictionary<string, Tuple<long, long>>();

bool IsInternetIdle()
{
    bool idle = true;
    NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
    foreach (var adapter in adapters)
    {
        var stats = adapter.GetIPStatistics();
        Tuple<long, long> info;
        if (!data.TryGetValue(adapter.Name, out info))
        {
            //New Adapter
            info = new Tuple<long, long>
            (
                stats .BytesReceived,
                stats .BytesSent
            );
            data.Add(adapter.Name, info);
        }
        else
        {
            if
            (
                info.Item1 != stats .BytesReceived
                || info.Item2 != stats .BytesSent
            )
            {
                idle = false;
                break;
            }
        }
    }
    //Console.WriteLine("Is Idle: {0}", idle.ToString());
    return idle;
}

И добавьте немного логики для обработки простоя:

// Fields
Stopwatch watch = new Stopwatch();

static TimeSpan? GetInternetIdleTime()
{
    if (IsInternetIdle())
    {
        if (!watch.IsRunning)
        {
            watch.Start();
        }
        //Console.WriteLine("Idle Time: {0}", XmlConvert.ToString(watch.Elapsed));
        return watch.Elapsed;
    }
    else
    {
        watch.Stop();
        watch.Reset();
        return null;
    }
}

Пример использования:

GetInternetIdleTime(); //preemptive call
Thread.Sleep(1000);
var result = GetInternetIdleTime();
if (result.HasValue)
{
    Console.WriteLine("Idle time: {0}", result.Value);
}
else
{
    Console.WriteLine("Not Idle");
}
Console.ReadKey();

Слова предостережения

  1. Не забудьте отписаться от вашего обработчика событий.
  2. Это предназначено для работы только в Windows.
  3. Помните, что первый запуск IsInternetIdle (описано выше) все сетевые адаптеры являются новыми. Вы можете сделать упреждающий вызов GetInternetIdleTime (описано выше), прежде чем заявлять об их использовании.
  4. Методы IsInternetIdle а также GetInternetIdleTime предназначены для использования только при наличии Интернета. Вы можете добавить проверки, чтобы увидеть, работают ли отдельные сетевые адаптеры.
  5. Результат GetInternetIdleTime Выше описано не общее время, когда соединения были неактивными, а время, когда было обнаружено, что соединения неактивны. Вы можете позвонить GetInternetIdleTime в таймере (если у вашего приложения есть основной цикл - скажем, это игра - вы можете вызывать его с заданной частотой).
  6. Если сетевой адаптер активен, это не значит, что он использует Интернет. Может быть, это связано с каким-то Интранетом. Невозможно определить, доступен ли "Интернет". Вы должны проверить связь с отдельными серверами самостоятельно. Не знаете что проверить? Это может быть проблематично, потому что DNS может быть переопределен локально... но вы можете попробовать http://example.org/, InterNIC.net или даже ntp.ord.

альтернатива

Так как это в любом случае для Windows, вы можете попробовать использовать WMI для информации о сетевых адаптерах, для этого я отсылаю вас к Найти только физические сетевые адаптеры с классом WMI Win32_NetworkAdapter от Mladen Prajdic.


Копать глубже

Вы можете эмулировать, что WireShark делает с помощью PCapDotNet, вы найдете примеры на http://codeproject.com/. Позвольте мне, DuckDuck, иди за тобой.

Другие вопросы по тегам