首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检测网络空闲时间

检测网络空闲时间
EN

Stack Overflow用户
提问于 2009-07-24 04:32:13
回答 1查看 1.3K关注 0票数 1

如何使用C#检测互联网何时空闲(没有下载/上传),并在此情况下启动下载?

EN

回答 1

Stack Overflow用户

发布于 2013-12-19 15:34:51

如果你在等待一个没有联系的时刻.你必须知道有很多连接,即使你认为你没有使用互联网。

试着看看WireShark普科蒙 (从sysitnerals)得到一个想法。

非工作交通

注意:如果您通过Mono在Mac或Linux上使用.NET,您应该知道这些API不能很好地移植到其他操作系统。所以,我在这里描述的只是Windows。

如果您想了解流量,可以尝试使用System.Net.NetworkInformation.IPGlobalStatistics

你可以这样做,像这样:

代码语言:javascript
复制
var properties = IPGlobalProperties.GetIPGlobalProperties();
// IPGlobalStatistics for IPv4
var ipv4stat = properties.GetIPv4GlobalStatistics();
// IPGlobalStatistics for IPv6
var ipv6stat = properties.GetIPv6GlobalStatistics();

来自MSDN示例

代码语言:javascript
复制
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。这样,如果Internet连接或断开连接(不要忘记取消订阅),您将得到通知事件。

示例:

代码语言:javascript
复制
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对象。您还可以读取OperationalStatus属性,以了解特定接口是否已打开。

示例:

代码语言:javascript
复制
 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);
 }

您需要做的是以查询该信息的方式存储该信息,以检查它是否已更改:

代码语言:javascript
复制
// 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;
}

并添加一些逻辑来处理空闲时间:

代码语言:javascript
复制
// 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;
    }
}

示例用法:

代码语言:javascript
复制
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. IsInternetIdleGetInternetIdleTime方法仅适用于互联网可用时使用。您可以添加检查以查看单个网络适配器是否已启动。
  5. 上面描述的GetInternetIdleTime的结果不是连接已经不活动的总时间,而是发现连接是非活动的时间。您可能需要在计时器中调用GetInternetIdleTime (如果应用程序有主循环--比如,这是一个游戏--您可以按给定的频率调用它)。
  6. 如果netwokr适配是活动的,这并不意味着它正在使用Internet。也许它是连接到某个内部网的。没有办法知道“互联网”是否是可触及的。您应该自己检查是否与单个服务器保持一致。不知道该查什么?这可能会有问题,因为DNS可能会在本地被高估.但是你可以试试example.orInterNIC.net,甚至ntp.ord

替代方案

因为这是针对Windows的,所以您可以尝试将WMI用于网络适配器信息,因此我将向您介绍Mladen的NetworkAdapter类

挖得更深

您可以通过使用WireShark来模拟PCapDotNet所做的事情,您可以在CodeProject.com上找到示例。让我来帮你DuckDuckGo说

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1175756

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档