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
You will need to know
Bytes sent from the beginning (To calculate average rate of transfer)
Bytes sent since last second (To calculate current transfer speed.)
This can be easily done if you know bytes sent from the beginning. (New bytes sent from the beginning - Bytes sent from the beginning 1 second ago)
(Bytes transfered / Total number of bytes)
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.
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);
Keep track of the time that the transfer is taking. The transfer rate is simply bytes transferred/seconds elapsed, in other words bytes per second. You don't need the total size for this. (You can also show % completed, which is bytes transferred/total bytes*100)