我正在写一个实用工具,将被上传一堆文件,并愿提供速率限制上传的选项。 什么是速度使用TcpClient类时限制上传的最佳方法? 我的第一直觉就是在时间的字节数量有限调用NetworkStream.Write()调用之间睡觉(以及跳过呼叫如果流不写完还)到缓冲器被上传。 有没有人实现这样的事情之前?
Answer 1:
实施限速是比较容易的,看看下面的代码片段:
const int OneSecond = 1000;
int SpeedLimit = 1024; // Speed limit 1kib/s
int Transmitted = 0;
Stopwatch Watch = new Stopwatch();
Watch.Start();
while(...)
{
// Your send logic, which return BytesTransmitted
Transmitted += BytesTransmitted;
// Check moment speed every five second, you can choose any value
int Elapsed = (int)Watch.ElapsedMilliseconds;
if (Elapsed > 5000)
{
int ExpectedTransmit = SpeedLimit * Elapsed / OneSecond;
int TransmitDelta = Transmitted - ExpectedTransmit;
// Speed limit exceeded, put thread into sleep
if (TransmitDelta > 0)
Thread.Wait(TransmitDelta * OneSecond / SpeedLimit);
Transmitted = 0;
Watch.Reset();
}
}
Watch.Stop();
这是未经测试的代码稿,但我认为这是足以让主要的想法。
Answer 2:
而不是创造,您还可能要考虑BITS(背景网络传输服务),它允许用户(或管理员)来配置的带宽,并且将处理转移排队。
它确实需要在服务器上的特定支持(包括IIS,但需要启用)。
Answer 3:
我知道这是一个古老的入口,但我认为这些信息可能是有用的人谁拿到这里通过谷歌或其他网络搜索。
如果我们使用张贴由“仲裁者”的解决方案,我们将发现,该线程将发送大量的数据,然后它会睡眠大量的时间,导致通常速度极限是每秒超过而32至200 kb的与STANDAR PC,线程可以在每秒10至100 MB管理。
我用了一个解决方案到我的项目。 请注意,这只是一段代码,你将不得不进行修改,以适应自己。 这是在Visual Basic编写。 顺便说一句,对不起,我的英语...
Dim SpeedLimit As Long = User.DownloadKbSpeedLimit * 1024, Elapsed As Long = 0
'Try to adjust buffersize to the operating system.
'Seem to be stupid, but the test shows it goes better this way.
If Environment.Is64BitOperatingSystem Then
stream.BufferSize = 64 * 1024
Else
stream.BufferSize = 32 * 1024
End If
'If buffersize is bigger than speedlimite, cut the buffersize to avoid send too much data
If SpeedLimit > 0 AndAlso e.BufferSize > SpeedLimit Then e.BufferSize = SpeedLimit
'Create Byte array to send data
Dim Buffer(e.BufferSize) As Byte
'Create Watch to control the speed
Dim Transmitted As Integer = 0, Watch As New Stopwatch()
Watch.Start()
'Start sending data
While True
'This enables the program to control another events or threads
System.Threading.Thread.Sleep(10)
Windows.Forms.Application.DoEvents()
'Recover data and write into the stream
If SpeedLimit = 0 OrElse Transmitted < SpeedLimit Then
Dim Readed As Integer = SomeFileStream.Read(Buffer, 0, Buffer.Length)
If Readed 0 Then Exit While
Stream.Write(Buffer, Readed)
Transmitted += Readed
End If
If Watch.ElapsedMilliseconds > OneSecond Then
Transmitted = 0
Watch.Restart()
End If
End While
Watch.Stop()
Stream.Close() : Stream.Dispose()
希望这可以帮助任何人。 再见。
Answer 4:
我做了TcpClient类的一些研究,这是我如何完成它:
'Throttle network Mbps...
bandwidthUsedThisSecond = session.bytesSentThisSecond + session.bytesRecievedThisSecond
If bandwidthTimer.AddMilliseconds(50) > Now And bandwidthUsedThisSecond >= (Mbps / 20) Then
While bandwidthTimer.AddMilliseconds(50) > Now
Thread.Sleep(1)
End While
End If
If bandwidthTimer.AddMilliseconds(50) <= Now Then
bandwidthTimer = Now
session.bytesRecievedThisSecond = 0
session.bytesSentThisSecond = 0
bandwidthUsedThisSecond = 0
End If
我敢肯定你知道如何将它转换为C#如果你决定自己虽然使用它,也许这只是我的代码,但它似乎比其他的答案更清晰。
这是在主回路,和bandwidthTimer为Date对象。
文章来源: How can I rate limit an upload using TcpClient?