This question already has an answer here:
im trying to calculate the transfer file speed per second using the average
i took the different between the sent bytes sum and the prevSum 5 times per second
im so confused because each time a change a little thing the speed value changes.. what's the correct solution for that ??
static long prevSum = 0;
static long[] rate = new long[5];
private static void SpeedPerSec(object o)
{
fileProgress fP = (fileProgress)o; //get the form conrtols
while (busy) // while sending file is active
{
for (int i = 0; i < rate.Length; i++)
{
//diff between the sent bytes and prev sent bytes
rate[i] = (sum - prevSum);
Thread.Sleep(1000/rate.Length);
}
prevSum = sum;
fP.RateLabel(Convert.ToInt64(rate.Average()));
//print the trasnfer rate which take a long value .. it just print the value in MB or KB string
}
}
here is the sendFile Code :
public static bool busy = false;
public static Socket client;
public static int packetSize = 1024*8;
public static int count = 0;
public static long fileSize;
public static long sum = 0;
public static void sendFile(string filePath)
{
// run the progres Form
Thread thFP = new Thread(fpRUN);
fileProgress fP = new fileProgress("Sending...");
thFP.Start(fP);
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
string fileName = Path.GetFileName(filePath);
byte[] fileData;
try
{
//sending file name and file size to the server
busy = true;
fileSize = fs.Length;
byte[] fileDetial = null;
string detail = fileName + "," + fileSize.ToString();
fileDetial = Encoding.ASCII.GetBytes(detail);
client.Send(fileDetial);
//sending file data to the server
fileData = new byte[packetSize];
count = 0;
sum = 0;
Thread thSpeed = new Thread(SpeedAndTimeLeft); //*here the thread of SPEED per second method
thSpeed.Start(fP);
fP.SizeLabel(fileSize); // tell the form the file size
Thread thClock = new Thread(fP.clock);
thClock.Start();
while (sum < fileSize)
{
fs.Seek(sum, SeekOrigin.Begin);
fs.Read(fileData, 0, fileData.Length);
count = client.Send(fileData, 0, fileData.Length, SocketFlags.None);
sum += count;
fP.ProgressBarFileHandler(sum,fileSize); //progressbar value
fP.SentLabel(sum, fileSize); //tell the form how much sent }
}
finally
{
busy = false;
fs.Close();
fileData = null;
MessageBox.Show(string.Format("{0} sent successfully", fileName));
}
}
I don't understand why you are using the long[] rate variable... If you want to calculate the transfer rate and update it each second you should store the current fileSize in a variable, and then after the sleep see the new fileSize. Then substract the previous fileSieze from the new one and you have the transfer rate for the last second (the live transfer rate). For the general transfer rate you should calculate it by taking a time-stamp when the download/upload started, and then, after each sleep calculate the rate by dividing the current fileSize with the total seconds passed so far.
Instead of calculating the average every time (which can become slow, if your rates array becomes very large), you can calculate it this way.
consider your rates to be these, for the sake of this example
long[] rates = new long[] { 5, 1, 3,4 ,2 ,5, 1};
you can calculate the average on each step like this:
double currentAverage = 0;
for (int i = 0; i < rates.Length; i++)
{
long currentRate = rates[i];
int iteration = i + 1;
currentAverage = (currentAverage * i + currentRate) / iteration;
}
Then just wait a second for each rate sample.
来源:https://stackoverflow.com/questions/9030297/calculate-sending-file-speed-sec-by-taking-the-average-of-5-times-of-sent-bytes