我正在編寫一個實用程序,它將上傳一堆文件,並希望提供限制上傳速度的選項。使用TcpClient類時,限速上傳的最佳方法是什麼?我的第一個直覺是一次調用NetworkStream.Write(),限制數量的字節,在兩次調用之間進行睡眠(並且在流尚未完成時跳過一個調用)直到緩衝區被上傳。有沒有人實施過這樣的事情?我如何評價使用TcpClient進行上傳?
回答
您可能還想考慮允許用戶(或管理員)配置帶寬並處理傳輸排隊的BITS(後臺Internet傳輸服務),而不是創建它。
它確實需要特定的服務器支持(包括在IIS中,但需要啓用)。
實施限速是比較容易的,看看下面的代碼片段:
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();
這是未經測試的代碼稿,但我認爲這是足以讓主要的想法。
我想你需要一個watch.restart,因爲它將經過的時間重置爲0,然後重新啓動計時器。 watch.reset只是將時間設置回0並停止itmer – zeocrash 2015-09-30 10:08:50
我知道這是一箇舊的條目,但我認爲這個信息可以用於通過谷歌或其他網絡搜索到達這裏的人有用。
如果我們使用「arbiter」發佈的解決方案,我們會發現線程會發送大量的數據,然後它會睡眠大量的時間,導致通常的速度限制超過32到200 kb每秒,而與標準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()
希望這可以幫助任何人。 再見。
感謝您的輸入。即使它是一個老話題,活動會引起它被注意:) – Luke 2010-09-03 00:27:41
我做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對象。
- 1. 使用tcpClient進行文件傳輸的奇數減速
- 2. 如何像HttpWebRequest一樣使用TcpClient進行HTTPS?
- 3. 如何在gerrit上進行評論?
- 4. 我如何使用JavaScript進行5星級評分
- 5. 如何獲得和評價使用C
- 6. XSLT - 如何評價
- 7. 如何評價我的聚類算法
- 8. 我如何評價限制git-svn?
- 9. 如何獲得使用TcpClient進行連接的基本應用程序?
- 10. 價值波紋管進行了評價剛纔
- 11. 如何將用戶使用FineUploader進行分組上傳?
- 12. 使用Schema.org使用copyrightHolder進行評論?
- 13. 如何使用dcast進行傳播?
- 14. 如何使用Express/Node.JS使用EJS進行降價?
- 15. 使用ASIFormDataRequest進行部分上傳
- 16. 使用Webdriver進行PrimeFaces文件上傳
- 17. 使用Django進行文件上傳
- 18. 使用Ajax進行文件上傳?
- 19. multipart使用NodeJS進行文件上傳
- 20. 使用CefSharp進行文件上傳
- 21. 使用aspupload進行Ajax文件上傳
- 22. 使用CSVHelper進行文件上傳
- 23. 使用CryptoJS進行上傳和加密
- 24. 使用Dropbox API進行塊上傳
- 25. 使用uplodify進行多文件上傳
- 26. 使用WLST進行遠程上傳
- 27. 使用的TcpClient
- 28. 如何使用價格*貨幣匯率對行進行分類?
- 29. 如何避免評價()
- 30. Javascript如何評價「this」?
嗯,不幸的是我的服務器在LAMP堆棧上,所以BITS不起作用。不過很高興知道。 – Luke 2009-06-30 14:13:17