计算上传传输速度问题
我已经实现了一个文件传输速率计算器来显示应用程序中发生的上传过程的 kB/秒,但是使用以下代码,似乎在文件开始上传后我的 KB/s 读数出现“突发”。
这是我的流代码的一部分,它使用 httpWebRequest 将文件以 1024 块的形式流式传输到服务器:
using (Stream httpWebRequestStream = httpWebRequest.GetRequestStream())
{
if (request.DataStream != null)
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
Debug.WriteLine("File Start");
var duration = new Stopwatch();
duration.Start();
while (true)
{
bytesRead = request.DataStream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
httpWebRequestStream.Write(buffer, 0, bytesRead);
totalBytes += bytesRead;
double bytesPerSecond = 0;
if (duration.Elapsed.TotalSeconds > 0)
bytesPerSecond = (totalBytes / duration.Elapsed.TotalSeconds);
Debug.WriteLine(((long)bytesPerSecond).FormatAsFileSize());
}
duration.Stop();
Debug.WriteLine("File End");
request.DataStream.Close();
}
}
现在上传过程的输出日志和相关的 kB/秒读数如下: (您会注意到一个新文件以“文件开始”和“文件结束”开始和结束)
File Start
5.19 MB
7.89 MB
9.35 MB
11.12 MB
12.2 MB
13.13 MB
13.84 MB
14.42 MB
41.97 kB
37.44 kB
41.17 kB
37.68 kB
40.81 kB
40.21 kB
33.8 kB
34.68 kB
33.34 kB
35.3 kB
33.92 kB
35.7 kB
34.36 kB
35.99 kB
34.7 kB
34.85 kB
File End
File Start
11.32 MB
14.7 MB
15.98 MB
17.82 MB
18.02 MB
18.88 MB
18.93 MB
19.44 MB
40.76 kB
36.53 kB
40.17 kB
36.99 kB
40.07 kB
37.27 kB
39.92 kB
37.44 kB
39.77 kB
36.49 kB
34.81 kB
36.63 kB
35.15 kB
36.82 kB
35.51 kB
37.04 kB
35.71 kB
37.13 kB
34.66 kB
33.6 kB
34.8 kB
33.96 kB
35.09 kB
34.1 kB
35.17 kB
34.34 kB
35.35 kB
34.28 kB
File End
我的问题是,您会注意到,我所说的“突发”从每个新文件的开头开始,以 MB 为峰值,然后正确地平衡。上传到这种程度就爆了正常吗?我的上传速度通常不会高于 40k/秒,所以它不可能是正确的。
这是一个真正的问题,当我平均显示最后 5 - 10 秒的屏幕显示时,它确实会产生约 3MB/秒的结果!
如果我以最好的方式解决这个问题,有什么想法吗?我应该做什么? :S
Graham
另外:为什么我不能执行 'bytesPerSecond = (bytesRead /uration.Elapsed.TotalSeconds)
' 并移动 period.Start &停止进入 while 循环并获得准确的结果?我本以为这样会更准确?每个速度读取为 900 字节/秒、800 字节/秒等。
I have implemented a file transfer rate calculator to display kB/sec for an upload process occuring in my app, however with the following code it seems I am getting 'bursts' in my KB/s readings just after the file commences to upload.
This is the portion of my stream code, this streams a file in 1024 chunks to a server using httpWebRequest:
using (Stream httpWebRequestStream = httpWebRequest.GetRequestStream())
{
if (request.DataStream != null)
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
Debug.WriteLine("File Start");
var duration = new Stopwatch();
duration.Start();
while (true)
{
bytesRead = request.DataStream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
httpWebRequestStream.Write(buffer, 0, bytesRead);
totalBytes += bytesRead;
double bytesPerSecond = 0;
if (duration.Elapsed.TotalSeconds > 0)
bytesPerSecond = (totalBytes / duration.Elapsed.TotalSeconds);
Debug.WriteLine(((long)bytesPerSecond).FormatAsFileSize());
}
duration.Stop();
Debug.WriteLine("File End");
request.DataStream.Close();
}
}
Now an output log of the upload process and associated kB/sec readings are as follows:
(You will note a new file starts and ends with 'File Start' and 'File End')
File Start
5.19 MB
7.89 MB
9.35 MB
11.12 MB
12.2 MB
13.13 MB
13.84 MB
14.42 MB
41.97 kB
37.44 kB
41.17 kB
37.68 kB
40.81 kB
40.21 kB
33.8 kB
34.68 kB
33.34 kB
35.3 kB
33.92 kB
35.7 kB
34.36 kB
35.99 kB
34.7 kB
34.85 kB
File End
File Start
11.32 MB
14.7 MB
15.98 MB
17.82 MB
18.02 MB
18.88 MB
18.93 MB
19.44 MB
40.76 kB
36.53 kB
40.17 kB
36.99 kB
40.07 kB
37.27 kB
39.92 kB
37.44 kB
39.77 kB
36.49 kB
34.81 kB
36.63 kB
35.15 kB
36.82 kB
35.51 kB
37.04 kB
35.71 kB
37.13 kB
34.66 kB
33.6 kB
34.8 kB
33.96 kB
35.09 kB
34.1 kB
35.17 kB
34.34 kB
35.35 kB
34.28 kB
File End
My problem is as you will notice, the 'burst' I am talking about starts at the beginning of every new file, peaking in MB's and then evens out properly. is this normal for an upload to burst like this? My upload speeds typically won't go higher than 40k/sec here so it can't be right.
This is a real issue, when I take an average of the last 5 - 10 seconds for on-screen display, it really throws things out producing a result around ~3MB/sec!
Any ideas if I am approaching this problem the best way? and what I should do? :S
Graham
Also: Why can't I do 'bytesPerSecond = (bytesRead / duration.Elapsed.TotalSeconds)
' and move duration.Start & duration.Stop into the while loop and receive accurate results? I would have thought this would be more accurate? Each speed reads as 900 bytes/sec, 800 bytes/sec etc.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我这样做的方法是:
保存以 long 形式传输的所有字节。
然后每隔 1 秒我检查一下已经传输了多少。所以我基本上只每秒触发一次代码来节省速度。在快速网络上,您的 while 循环将在一秒钟内循环 maaaaaaaaaaa 任意次。
根据网络的速度,您可能需要检查在单独的线程或函数中传输的字节。我更喜欢使用计时器来完成此操作,这样我就可以轻松更新 UI
编辑:
从你看你的代码,我猜你做错了什么是你没有考虑到 while(true) 中的一个循环不是 1 秒
编辑2:
每秒只进行一次速度检查的另一个优点是事情会进展得更快。在这种情况下,更新 UI 可能是您所做的最慢的事情,因此,如果您尝试每个循环更新 UI,那很可能是最慢的点,并且会产生无响应的 UI。
您还纠正了您应该对这些值进行平均,这样您就不会得到 microsoft 分钟错误。我通常在运行的 Timer 函数中通过执行以下操作来执行此操作:
The way i do this is:
Save up all bytes transfered in a long.
Then every 1 second i check how much has been transfered. So i basicly only trigger the code to save speed once pr second. Your while loop is going to loop maaaaaaaaaaaany times in one second on a fast network.
Depending on the speed of your network you may need to check the bytes transfered in a seperate thread or function. I prefere doing this with a Timer so i can easly update UI
EDIT:
From your looking at your code, im guessing what your doing wrong is that you dont take into account that one loop in the while(true) is not 1 second
EDIT2:
Another advatage with only doing the speed check once pr second is that things will go much quicker. In cases like this updating the UI can be the slowest thing your are doing, so if you try to update the UI every loop, thats most likely your slowest point and is going to produce unresponsive UI.
Your also correct that you should avarage out the values, so you dont get the microsoft minutes bugs. I normaly do this in the Timer function running by doing something like this:
您和要发送到的系统之间有许多软件和硬件层,其中几个层具有一定量的可用缓冲区空间。
当您第一次开始发送时,您可以很快地输出数据,直到填满这些缓冲区 - 但实际上它并没有那么快到达另一端!填满发送缓冲区后,您只能以与耗尽相同的速率将更多数据放入其中,因此您看到的速率将下降到底层网络发送速率。
There's many layers of software and hardware between you and the system you're sending to, and several of those layers have a certain amount of buffer space available.
When you first start sending, you can pump out data quite quickly until you fill those buffers - it's not actually getting all the way to the other end that fast, though! After you fill up the send buffers, you're limited to putting more data into them at the same rate it's draining out, so the rate you see will drop to the underlying networking sending rate.
所有,我想我已经通过调整 5 - 10 平均变量等待一秒钟来解决突发问题,这不是最好的,但可以让互联网自行解决并让我捕获平稳的传输。
从我的网络流量来看,它的右下角正在爆发,因此代码中没有任何内容我可以采取不同的措施来阻止这种情况。
在我犹豫地接受我自己的答案之前,请仍然对更多答案感兴趣。
All, I think I have fixed my issue by adjusting the 5 - 10 averging variable to wait one second to account for the burst, not the best, but will allow internet to sort itself out and allow me to capture a smooth transfer.
It appears from my network traffic it down right is bursting so there is nothing in code I could do differently to stop this.
Please will still be interested in more answers before I hesitantly accept my own.