tags:

views:

2199

answers:

6
+8  Q: 

C#: bandwidth

Is there any way i can calculate bandwidth (packets sent and received) by an exe/application via net? have loooked into IPGlobalProperties,

and other classes .... i want packets sent n received by a single application.. i have checked http://netstatagent.com/ I need something similar... is there anything in .net which can help me?

My app connects to web service to send some image files... and also receives files...

+11  A: 

One way is to retrieve the value of the performance counters ".NET CLR Networking/Bytes Received" and ".NET CLR Networking/Bytes Sent" for your application:

PerformanceCounter bytesSentPerformanceCounter= new PerformanceCounter();
bytesSentPerformanceCounter.CategoryName = ".NET CLR Networking";
bytesSentPerformanceCounter.CounterName = "Bytes Sent";
bytesSentPerformanceCounter.InstanceName = GetInstanceName();
bytesSentPerformanceCounter.ReadOnly = true;

float bytesSent = bytesSentPerformanceCounter.NextValue();

//....

private static string GetInstanceName()
{
  // Used Reflector to find the correct formatting:
  string assemblyName = GetAssemblyName();
  if ((assemblyName == null) || (assemblyName.Length == 0))
  {
    assemblyName = AppDomain.CurrentDomain.FriendlyName;
  }
  StringBuilder builder = new StringBuilder(assemblyName);
  for (int i = 0; i < builder.Length; i++)
  {
    switch (builder[i])
    {
      case '/':
      case '\\':
      case '#':
        builder[i] = '_';
        break;
      case '(':
        builder[i] = '[';
        break;

      case ')':
        builder[i] = ']';
        break;
    }
  }
  return string.Format(CultureInfo.CurrentCulture, 
                       "{0}[{1}]", 
                       builder.ToString(), 
                       Process.GetCurrentProcess().Id);
}

private static string GetAssemblyName()
{
  string str = null;
  Assembly entryAssembly = Assembly.GetEntryAssembly();
  if (entryAssembly != null)
  {
    AssemblyName name = entryAssembly.GetName();
    if (name != null)
    {
      str = name.Name;
    }
  }
  return str;
}

Note that the performance-counters aren't created until the first time you use the relevant network libraries (you will get InvalidOperation : Instance 'XXX' does not exist in the specified Category) and that you need to insert

<configuration>
  <system.net>
    <settings>
      <performanceCounters enabled="true" />
    </settings>
  </system.net>
</configuration>

in your app.config.

For a full sample download NetworkTraffic.cs and NetworkTraffic.exe.config.

Rasmus Faber
A: 

Hi Rasmus, i m lookin for bytes/sec per application... not for the whole computer ....Doesnt seem to be working for a console appl... Error message:"console app does not exist in the specified Category."

There are instances of the performance counters for each process. You use the InstanceName property to select which one you want. (PS. you should add a comment rather than an answer for something like this).
Rasmus Faber
See my updated post.
Rasmus Faber
A: 

This does not work... as far as i know bytesSentPerformanceCounter.InstanceName ="" // here you need to give network card name ...

InstanceName is the name of the instance of the PerformanceCounter. The CLR formats it exactly as in the code I wrote, basically "ApplicationName[ProcessId]". Try downloading the code I attached to the original post. It works perfectly for me (Vista 32 bit, .Net 2.0).
Rasmus Faber
Hi Rasmus, Thanks for your code ... its working perfectly... However the bytes sent and received is always 0 ... I gotta say you certainly are very knowledgeable in this area of .net... I cant add comment as "commenting requires 50 reputation"
Hi Rasmus, i guess i solved it .... thanks a lot .. God bless you man...
Rasmus, i was wondering if you could point me to a good resource for performance counters.. maybe a book ...
Sorry. I can't think of any good resources. Perhaps you should ask this as a separate question?
Rasmus Faber
A: 

Hi Rasmus, somehow the bytes sent is way too less than bytes received... its not that i m browsing net from my application... I send to the web service images(as bytes) and other XML files (few kbs as string input to web service function). In return i sometimes return error codes or bool... still the bytes sent is way too less than received... received is 5 times more...i m puzzled...

Try using WireShark to look at the data actually sent and received. And doublecheck that you haven't switched received and sent. You could also try inspecting the performance counters using the performance monitor.
Rasmus Faber
+2  A: 

I remembered reading an article about this and dug it up for you, http://nayyeri.net/blog/how-to-calculate-network-utilization-in-net/

an excerpt before their code:

.NET comes with three performance counters for the used parameters in network utilization formula out of the box. All of these counters are located in Network Interface category and are named "Bytes Sent/sec", "Bytes Received/sec" and "Current Bandwidth". The only parameter that requires some extra effort to be calculated is time_in_sec.

"Bytes Sent/sec" and "Bytes Received/sec" counters calculate their values based on different samples and the best way to get a better value from these counters is finding the summation of their values in a loop because in some cases their values may be zero or very different from the real state of the network. Then we can find the time_in_sec parameter by finding the number of times that the loop is iterated because our performance counters find their values for one seconds the overall time in seconds is equal to the number of iterations.

ccook
A: 

For me the bytes sent and received is always 0 any idea how u resolve that

dev
0 down vote For me the bytes sent and received is always 0 any idea how u resolve that
dev