Search code examples
c#bandwidthtcpclienttransfer

Measure data transfer rate over tcp using c#


I am sending a huge file over TCP using C#, and would like to measure the download speed. How can I capture the transfer rate every second? If I use IPv4InterfaceStatistics or a similar method, I capture the device transfer rate instead of capturing the file transfer rate. The problem with capturing device transfer rate is that it captures all data passing through the network device instead of the single file that I transfer.

How can I capture the file transfer rate?


Solution

  • Since you don't have control over the stream to tell how much is read, you can create timestamps before and after a stream read and then calculate the speed based on the number of received or sent bytes:

    using System.IO;
    using System.Net;
    using System.Diagnostics;
    
    // some code here...
    
    Stopwatch stopwatch = new Stopwatch();
    
    // Begining of the loop
    
    int offset = 0;
    stopwatch.Reset();
    stopwatch.Start();
    
    bytes[] buffer = new bytes[1024]; // 1 KB buffer
    int actualReadBytes = myStream.Read(buffer, offset, buffer.Length);
    
    // Now we have read 'actualReadBytes' bytes 
    // in 'stopWath.ElapsedMilliseconds' milliseconds.
    
    stopwatch.Stop();
    offset += actualReadBytes;
    int speed = (actualReadBytes * 8) / stopwatch.ElapsedMilliseconds; // kbps
    
    // End of the loop
    

    You should put the Stream.Read in a try/catch block and handle exceptions that could occur. It's the same for writing to streams and calculating the speed, only these two lines are affected:

    myStream.Write(buffer, 0, buffer.Length);
    int speed = (buffer.Length * 8) / stopwatch.ElapsedMilliseconds; // kbps