计算使用套接字tcp c#发送文件的每秒速度和剩余时间
本文关键字:速度 余时间 时间 tcp 套接字 文件 计算使用 | 更新日期: 2023-09-27 18:21:38
如何计算每秒的速度和以秒为单位的剩余时间?我试过使用:
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
long prevSum = 0;
while (fileTransfer.busy) {
rate = (fileTransfer.sum - prevSum);
RateLabel(rate); //converting prevSum to (int)KB/SEC
if (rate != 0)
left = (fileTransfer.fileSize - fileTransfer.sum) / rate;
TimeSpan t = TimeSpan.FromSeconds(left);
timeLeftLabel(FormatRemainingText(rate, t)); //show how much left
prevSum = fileTransfer.sum;
Thread.Sleep(1000);
}
}
但是速率和剩余时间像(30MB/秒然后5MB/秒)那样永久地上下波动。
这是发送文件代码:
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;
fP.SizeLabel(fileSize); // tell the form the file size
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); //tell the form how much sent
}
}
finally {
busy = false;
fs.Close();
fileData = null;
MessageBox.Show(string.Format("{0} sent successfully", fileName));
}
}
我该怎么解决?有没有更好的方法来计算速度?
您可以对传输速度进行一些平滑处理,以避免值的跳跃。看见http://en.wikipedia.org/wiki/Moving_average一个选项。基本上计算速度随时间变化的某种平均值。
你无法解决这个问题。"修复"它的唯一方法是创建一个恒定速度的网络/互联网。
网络(和您的计算机)的速度不是恒定的。
计算告诉你它是什么。
形式构造函数
Timer timer1 = new Time();
public Form1()
{
InitializeComponent();
this.timer1.Enabled = true;
this.timer1.Interval = 1000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
}
或者从工具箱中添加,并设置以前的值
发送字节的总和应该是公共的,这样我们的方法可以每秒获得其值
long sentBytes = 0; //the sent bytes that updated from sending method
long prevSentBytes = 0; //which references to the previous sentByte
double totalSeconds = 0; //seconds counter to show total time .. it increases everytime the timer1 ticks.
private void timer1_Tick(object sender, EventArgs e)
{
long speed = sentBytes - prevSentBytes ; //here's the Transfer-Rate or Speed
prevSentBytes = sentBytes ;
labelSpeed.Text = CnvrtUnit(speed) + "/S"; //display the speed like (100 kb/s) to a label
if (speed > 0) //considering that the speed would be 0 sometimes.. we avoid dividing on 0 exception
{
totalSeconds++; //increasing total-time
labelTime.Text = TimeToText(TimeSpan.FromSeconds((sizeAll - sumAll) / speed));
//displaying time-left in label
labelTotalTime.Text = TimeToText(TimeSpan.FromSeconds(totalSeconds));
//displaying total-time in label
}
}
private string TimeToText(TimeSpan t)
{
return string.Format("{2:D2}:{1:D2}:{0:D2}", t.Seconds, t.Minutes, t.Hours);
}
private string CnvrtUnit(long source)
{
const int byteConversion = 1024;
double bytes = Convert.ToDouble(source);
if (bytes >= Math.Pow(byteConversion, 3)) //GB Range
{
return string.Concat(Math.Round(bytes / Math.Pow(byteConversion, 3), 2), " GB");
}
else if (bytes >= Math.Pow(byteConversion, 2)) //MB Range
{
return string.Concat(Math.Round(bytes / Math.Pow(byteConversion, 2), 2), " MB");
}
else if (bytes >= byteConversion) //KB Range
{
return string.Concat(Math.Round(bytes / byteConversion, 2), " KB");
}
else //Bytes
{
return string.Concat(bytes, " Bytes");
}
}