tags:

views:

1679

answers:

6

Hi freinds,

As a feature in the application which Im developing, I need to show the total estimated time left to upload/download a file to/from server.

how would it possible to get the download/upload speed to the server from client machine.

i think if im able to get speed then i can calculate time by -->

for example ---for a 200 Mb file = 200(1024 kb) = 204800 kb and divide it by 204800 Mb / speed Kb/s = "x" seconds

Can anybody help me with this..

Thanks in advance.

+8  A: 

The upload/download speed is no static property of a server, it depends on your specific connection and may also vary over time. Most application I've seen do an estimation over a short time window. That means they start downloading/uploading and measure the amount of data over, lets say 10 seconds. This is then taken as the current transfer speed and used to calculate the remaining time (e.g. 2500kB / 10s -> 250Kb/s). The time window is moved on and recalculated continuously to keep the calculation accurate to the current speed.

Although this is a quite basic approach, it will serve well in most cases.

Frank Bollack
This, I believe, is the technique use by Window's file copy dialog.
Martin Brown
+2  A: 

This is only tangentially related, but I assume if you're trying to calculate total time remaining, you're probably also going to be showing it as some kind of progress bar. If so, you should read this paper by Chris Harrison about perceptual differences. Here's the conclusion straight from his paper (emphasis mine).

Different progress bar behaviors appear to have a significant effect on user perception of process duration. By minimizing negative behaviors and incorporating positive behaviors, one can effectively make progress bars and their associated processes appear faster. Additionally, if elements of a multistage operation can be rearranged, it may be possible to reorder the stages in a more pleasing and seemingly faster sequence.

http://www.chrisharrison.net/projects/progressbars/ProgBarHarrison.pdf

Nic
Very clever. I will attempt to apply this to an application tonight.
Gregory
thanks nic for the link..
Andy
A: 

I don't know why do you need this but i would go simpliest way possible and ask user what connection type he has. Then take file size divide it by speed and then by 8 to get number of seconds.

Point is you won't need processing power to calculate speeds. Microsoft on their website use function that calculates a speed for most default connections based on file size which you can get while uploading the file or to enter it manually.

Again, maybe you have other needs and you must calculate upload on fly...

eugeneK
A: 

Try something like this:

int chunkSize = 1024;
int sent = 0
int total = reader.Length;
DateTime started = DateTime.Now;
while (reader.Position < reader.Length)
{
    byte[] buffer = new byte[
        Math.Min(chunkSize, reader.Length - reader.Position)];
    readBytes = reader.Read(buffer, 0, buffer.Length);

    // send data packet

    sent += readBytes;
    TimeSpan elapsedTime = DateTime.Now - started;
    TimeSpan estimatedTime = 
        TimeSpan.FromSeconds(
            (total - sent) / 
            ((double)sent  / elapsedTime.TotalSeconds));
}
Rubens Farias
Thanks Rubens...
Andy
A: 

The following code computes the remaining time in minute.

    long totalRecieved = 0;
    DateTime lastProgressChange = DateTime.Now;
    Stack<int> timeSatck = new Stack<int>(5);
    Stack<long> byteSatck = new Stack<long>(5);

    using (WebClient c = new WebClient())
    {
        c.DownloadProgressChanged += delegate(object s, DownloadProgressChangedEventArgs args)
        {
            long bytes;

            if (totalRecieved == 0)
            {
                totalRecieved = args.BytesReceived;
                bytes = args.BytesReceived;
            }
            else
            {
                bytes = args.BytesReceived - totalRecieved;
            }

            timeSatck.Push(DateTime.Now.Subtract(lastProgressChange).Seconds);
            byteSatck.Push(bytes);

            double r = timeSatck.Average() * ((args.TotalBytesToReceive - args.BytesReceived) / byteSatck.Average());
            this.textBox1.Text = (r / 60).ToString();

            totalRecieved = args.BytesReceived;
            lastProgressChange = DateTime.Now;
        };

        c.DownloadFileAsync(new Uri("http://www.visualsvn.com/files/VisualSVN-1.7.6.msi"), @"C:\SVN.msi");
    }
Mehdi Golchin
HI Mehdi,Could you please let me know how to give uri - like if server url is http://webxxx.com and file is "a.doc."is this below uri is correct..??c.UploadFileAsync(new Uri(hostName+"/a.doc"),"POST", @"C:\servertest\a.doc");
Andy
A: 

I think I ve got the estimated time to download.

double timeToDownload = ((((totalFileSize/1024)-((fileStream.Length)/1024)) / Math.Round(currentSpeed, 2))/60);
this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { 
Math.Round(currentSpeed, 2), Math.Round(timeToDownload,2) });

where

private void UpdateProgress(double currentSpeed, double timeToDownload)
    {

        lblTimeUpdate.Text = string.Empty;
        lblTimeUpdate.Text = " At Speed of " + currentSpeed + " it takes " + timeToDownload +"   minute to complete download";
    }

and current speed is calculated like

TimeSpan dElapsed = DateTime.Now - dStart;
if (dElapsed.Seconds > 0) {currentSpeed = (fileStream.Length / 1024) / dElapsed.Seconds;
                                }
Andy