Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating Connection/Download Speed

I have a client and server program (both in Obj-C) and I am transferring files between two devices using the programs.

The transferring is working fine, but I would like to display to the user what transfer rate they are getting.

So I know the total size of the file, and how much of the file has been transferred, is there a way to figure out the transfer rate from this information, and if not, what information do I need to calculate the transfer rate?

Thanks

like image 585
kdbdallas Avatar asked Dec 16 '08 07:12

kdbdallas


People also ask

How long should it take to download 1GB?

A 100Mbps (megabits per second) fibre connection will give you a download speed of 12.5MBps (megabytes per second). A 1GB file is equal to 1024MB, so it should take 81.9 seconds to download the file.

Can you calculate the internet speed?

There are plenty of apps and websites that will test the speed of your connection. Some of the more popular speed test services include Speedtest.net, Fast.com or CloudFlare. Whether you install an app or use a website, it's a good idea to run the test a few times to get a sense of your connection's performance.


2 Answers

The naïve way is bytes_downloaded / (now - start_time), but that becomes inaccurate if the connection speed fluctuates wildly, or if the user starts another download (perhaps in another app) halfway through your download. Both of these may happen if the user runs a torrent in the background.

A better way (though harder to implement) is to keep an array of periodic samples and present the average.

Start out with an array containing 0. The array is of samples, and each sample is the number of bytes downloaded since the previous sample. Then start the download.

Every half-second (you can try different intervals), measure how many bytes you've downloaded, then subtract the previous total from this new total. Add the difference as the new last element in the array. If this grows the array beyond a certain size, lop off the first element (oldest sample). Then, present the average of all the samples.

You should keep somewhere between 2–5 seconds' worth of samples, and the interval should be somewhere between 0.5 and 1 seconds (it's a trade-off between currency and performance).

You may also want to remove the first element from the array after retrieving it if it is zero. This makes your starting reportage more accurate and helps you recover more quickly from stalls, since you're not including old zeroes in the average.

like image 163
Peter Hosey Avatar answered Oct 20 '22 19:10

Peter Hosey


As soon as you start the download, capture the current system time and store it as the "start time". Then, all you need to do to calculate transfer speed at any point during the transfer is to look at the system time again and use it as the "current time" to calculate the total time spent so far:

transfer_speed = bytes_transferred / ( current_time - start_time)

You probably want to use second or millisecond accuracy with the times, and of course can multiply the result by 8 if you want bits/second.

Since you're using Cocoa, you could use the NSDate class to get the timestamps. For example, use the following when you start the transfer:

NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];

Then periodically check the transfer rate by using:

double speed = bytesTransferred / ([NSDate timeIntervalSinceReferenceDate] - start);
like image 33
Marc Novakowski Avatar answered Oct 20 '22 18:10

Marc Novakowski