How do I detect when the internet is idle (no download/upload) using C#, and initiate a download when it is?
-
You might want to look at rephrasing your question and being a little more specific. – Kane Jul 24 '09 at 04:32
-
Here is a similar SO question to yours that you might find useful: [http://stackoverflow.com/questions/566139/detecting-network-connection-speed-and-bandwidth-usage-in-c](http://stackoverflow.com/questions/566139/detecting-network-connection-speed-and-bandwidth-usage-in-c) – quickcel Jul 24 '09 at 04:35
1 Answers
If you are waiting for a moment where there are no connections... you have to know that there are a lot of connections even when you think you are not using Internet.
Try giving a look at WireShark and Prcomon (from sysitnerals) to have an idea.
Notwork traffic
Note: if you are using .NET on Mac or Linux via Mono, you should know that this APIs don't port well to other operating systems. So, what I describe here is only for Windows.
If what you want is to have an idea of the traffic, you can try using System.Net.NetworkInformation.IPGlobalStatistics.
You can do so, like this:
var properties = IPGlobalProperties.GetIPGlobalProperties();
// IPGlobalStatistics for IPv4
var ipv4stat = properties.GetIPv4GlobalStatistics();
// IPGlobalStatistics for IPv6
var ipv6stat = properties.GetIPv6GlobalStatistics();
From the example at 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("");
Is Internet Available?
If you need to get a notification when the Internet is avaliable, you can subscribe to System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged. That way you will get a notification event if the Internet is connected or disconnected (Don't forget to unsubscribe).
Example:
var handler = new NetworkAddressChangedEventHandler
(
(sender, args) =>
{
//handle notification
}
);
System.Net.NetworkInformation.NetworkChange += handler;
// Unsubscribe:
System.Net.NetworkInformation.NetworkChange -= handler;
You may be interested in knowing what Network adapters are Up or Down and how much traffic each one has... for that see below.
Idle & Idle time
Let's define "Idle". I would say "Idle" means that the Internet is available (check above), and if it hasn't been used for a given ammount of time.
So, the other thing you got to do is is calling NetworkInterface.GetAllNetworkInterfaces that will give you an array of System.Net.NetworkInformation.NetworkInterface on which you can call the method GetIPStatistics to get an IPStatistics object for that particular netowork interface. You can also read the OperationalStatus property to know if the particular interface is Up or not
Example:
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);
}
What you will need to do is store this information in a way you can query it, to check if it has changed:
// 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;
}
And add some logic to handle idle time:
// 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;
}
}
Example usage:
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();
Words of caution
- Remember to unsubscribe your event handler.
- This is intended to work on Windows only.
- Remember that the first run of
IsInternetIdle
(described above) all the network adapters are new. You may want to do a preemptive call toGetInternetIdleTime
(described above) before stating using them. - The methods
IsInternetIdle
andGetInternetIdleTime
are intended to be used only when Internet is available. You could add checks to see if the individual network adapters are Up. - The result of
GetInternetIdleTime
described above is not the total time that the connections has been inactive, but the time since it was discovered that the connections are inactive. You may want to callGetInternetIdleTime
in a timer (of if your application has a main loop - say, it's a game - you can call it with a given frequency). - If a netwokr adaptes is Active, it doesn't mean that it is using Internet. Maybe it is connected to some Intranet. There is no way to tell if "Internet" is reachable. You should check for conectivity with individual servers yourself. Don't know what to check? It can be problematic because DNS can be overrrided locally... but you can try example.or, InterNIC.net or even ntp.ord.
Alternative
Since this is for Windows anyway, you can try using WMI to the network adapters information, for that I'll refer you to Find only physical network adapters with WMI Win32_NetworkAdapter class by Mladen Prajdic.
Digging deeper
You can emulate what WireShark does by using PCapDotNet, you will find examples at CodeProject.com. Let me DuckDuckGo that for you.

- 31,890
- 5
- 57
- 86