私は、たくさんのファイルをアップロードするユーティリティを書いています。レート制限のアップロードにオプションを提供したいと考えています。 TcpClientクラスを使用しているときにレート制限のアップロードに最適な方法は何ですか?私の最初の本能は、一度に限られた数のバイトでNetworkStream.Write()を呼び出すことです。バッファがアップロードされるまで、コール間でスリープします(ストリームがまだ書き込まれていない場合は呼び出しをスキップします)。誰もこれの前にこのような何かを実装しましたか?TcpClientを使用してアップロードを制限するにはどうすればよいですか?
答えて
これを作成するのではなく、ユーザー(または管理者)が帯域幅を設定できるBITS(バックグラウンドインターネット転送サービス)を検討し、転送のキューイングを処理することも考えられます。
サーバーでの特定のサポートが必要です(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
私はこれが古いエントリだと知っていますが、私はこの情報は、Googleや別のWeb検索を介してここにいる人にとって有益だと思います。
「アービター」によって投稿されたソリューションを使用すると、スレッドが大量のデータを送信し、通常は速度制限が32〜200を超えるため、大量の時間スリープ状態になることがわかりますkb /秒、スタンドアロンのPCの場合、スレッドは10〜100MB /秒を管理できます。
私は自分のプロジェクトに次のソリューションを使用しました。コードは単なるコードであり、独自のコードに変更する必要があります。これは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
私がれる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. 規制を使用して多くのルートを制限するにはどうすればよいですか?
- 2. テキストボックスに数字キーを使用してユーザーフォームを制限するにはどうすればよいですか?
- 3. これらの制限(ビジネス制限)を適用するにはどうすればよいですか?
- 4. htaccessを使用してエントリへのアクセスを制限するにはどうすればよいですか?
- 5. CORSを使用してAWS S3アクセスを制限するにはどうすればよいですか?
- 6. Git Push APIを使用してGit Pushを制限するにはどうすればよいですか?
- 7. グループメンバーシップを使用して結果を制限するにはどうすればよいですか?
- 8. Webpack/Bootstrapで使用されるフォント形式を制限するにはどうすればよいですか?
- 9. LandscapeでmodalViewControllerを制限するにはどうすればよいですか?
- 10. アプリケーション内でダウンロード/アップロードの速度を制限するにはどうすればよいですか?
- 11. wsgiで大きなファイルのアップロードを制限するにはどうすればよいですか?
- 12. ジェネリックインターフェイスで使用するタイプを制限するにはどうすればよいですか?
- 13. LinkedTransferQueueのサイズを制限するにはどうすればよいですか?
- 14. ウェブサイトのリフレッシュレートを制限するにはどうすればよいですか?
- 15. テキストフィールドのサイズを制限するにはどうすればよいですか?
- 16. htmlファイルのアップロード数を制限するにはどうすればよいですか?
- 17. docker jwilder/nginx-proxyのアップロード制限を変更するにはどうすればよいですか?
- 18. スプリングステートマシンのインスタンスが使用するスレッド数を制限するにはどうすればよいですか?
- 19. goユニットテストでメモリ使用量を制限するにはどうすればよいですか
- 20. ドメインが無制限のアプリでマップを使用するにはどうすればよいですか?
- 21. Thymeleaf:#numbers.sequence()を可変制限付きで使用するにはどうすればよいですか?
- 22. すでに限定されたクエリを制限するにはどうすればよいですか?
- 23. HTTPおよびコマンドラインツールを使用してファイルをアップロードするにはどうすればよいですか?
- 24. Android用Salesforce Mobile SDKを使用してファイルをアップロードするにはどうすればよいですか?
- 25. イメージモジュールを使用して、イメージをリモートでDrupalにアップロードするにはどうすればよいですか?
- 26. Web UIを使用してdevユーザのシェフサーバへのアップロードを制限するにはどうすればよいですか?
- 27. AndroidのCPU使用量を制限するにはどうすればよいですか?
- 28. リモートAPIを使用している場合、エンティティを読み取るようにユーザーを制限するにはどうすればよいですか?
- 29. レート制限なしでユーザー名がTwitterで使用されているかどうかを確認するにはどうすればいいですか?
- 30. nativescriptでマルチパートフォームデータを使用してファイルをアップロードするにはどうすればよいですか?
残念ながら私のサーバーはLAMPスタック上にあり、BITSは動作しません。しかし、よく知っている。 – Luke