Ich schreibe ein Dienstprogramm, das eine Reihe von Dateien hochladen wird, und möchte die Möglichkeit bieten, Limit-Uploads zu bewerten. Was ist der beste Ansatz für die Rate-limiting-Uploads bei Verwendung der TcpClient-Klasse? Mein erster Instinkt besteht darin, NetworkStream.Write() mit einer begrenzten Anzahl von Bytes gleichzeitig aufzurufen, zwischen den Aufrufen zu schlafen (und einen Anruf zu überspringen, wenn der Stream noch nicht fertig geschrieben ist), bis der Puffer hochgeladen ist. Hat jemand so etwas schon mal umgesetzt?Wie kann ich einen Upload mit TcpClient einschränken?
Antwort
Anstatt dies zu erstellen, sollten Sie auch BITS (Background Internet Transfer Service) in Betracht ziehen, mit dem der Benutzer (oder Administrator) die Bandbreite konfigurieren und Warteschlangen von Übertragungen verarbeiten kann.
Es erfordert spezielle Unterstützung auf dem Server (einschließlich in IIS, muss aber aktiviert werden).
Geschwindigkeitsbegrenzung Implementierung ist relativ einfach, werfen Sie einen Blick auf die folgenden Ausschnitt:
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();
Dieser Entwurf ungetesteten Code ist, aber ich denke, es ist genug, um die Hauptidee zu bekommen.
Ich denke, dass Sie eine watch.restart dort als die abgelaufene Zeit zurück auf 0 zurückgesetzt und dann den Timer neu starten möchten. watch.reset setzt die Zeit einfach auf 0 zurück und stoppt den itmer – zeocrash
Ich weiß, dass dies ein alter Eintrag ist, aber ich denke, dass diese Informationen für jemanden nützlich sein können, der durch Google oder eine andere Websuche hierher kommt.
Wenn wir die Lösung verwenden, die von "arbiter" gepostet wird, werden wir feststellen, dass der Thread eine große Menge an Daten senden wird und dann für eine lange Zeit schlafen wird, da die Geschwindigkeitsbegrenzungen normalerweise zwischen 32 und 200 liegen Bei einem Standard-PC kann der Thread über 10 bis 100 MB pro Sekunde verwalten.
Ich habe die nächste Lösung in meinem Projekt verwendet. Beachten Sie, dass es sich nur um ein Stück Code handelt, und Sie müssen es ändern, um es an Ihre eigenen anzupassen. Es ist in Visual Basic schreiben. Übrigens, sorry über mein Englisch ...
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()
Hoffe, dass dies jedem helfen kann. Tschüss.
Danke für die Eingabe. Obwohl es ein altes Thema ist, wird die Aktivität dafür sorgen, dass es bemerkt wird :) – Luke
Ich habe einige Nachforschungen über die TcpClient Klasse und das ist, wie ich es erreicht:
'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
Ich bin sicher, Sie wissen, wie es zu C# zu konvertieren, wenn Sie es sich allerdings zu bedienen und es ist vielleicht nur mein Code, aber es scheint klarer als die anderen Antworten.
Dies ist in der Hauptschleife, und bandwidthTimer ist ein Date-Objekt.
- 1. Datei-Upload-Typen auf Django einschränken
- 2. Wie kann ich Anmeldeinformationen in Jenkins einschränken?
- 3. S3 Multipart Upload: Wie kann ich einen abbrechen?
- 4. Wie kann ich einen Datei-Upload in Rails testen?
- 5. Wie bekomme ich Client-IP-Adresse mit TcpClient?
- 6. Wie kann man einen Benutzer in asp.net einschränken?
- 7. Warum kann ich nvarchar (max) nicht einschränken?
- 8. Kommunikation mit einem HTTP-Proxy über einen .NET TcpClient
- 9. Einschränken von Dateitypen in JQuery Datei-Upload-Demo
- 10. Wie cluster ich einen Upload-Ordner mit ASP.Net?
- 11. Wie kann man private Inhalte einschränken?
- 12. TcpClient Bandbreitenschätzung
- 13. Wie kann ich einschränken IE-Benutzer meine Seite zu sehen?
- 14. Wie kann ich die Markdown-Syntax in Ruby einschränken?
- 15. TcpClient entsorgen
- 16. Wie kann man SignalR Server Verbindungen einschränken?
- 17. Wie kann ich den Benutzerzugriff auf Servlets & Jsp's behandeln/einschränken?
- 18. Wie kann ich den Zugriff auf meinen PHP-Quellcode einschränken?
- 19. Wie kann ich einen generischen Parameter einschränken, um grundlegende mathematische Operatoren zu implementieren?
- 20. Wie kann ich ein Upload-Datei-Element mit Javascript verstecken?
- 21. Wie kann ich mit FileReference Upload eine andere Variable senden?
- 22. Benutzereingaben mit Javascript einschränken
- 23. Wie kann ich CREATE TABLE-Zugriff für einen Benutzer auf ein bestimmtes Schema (SQL-Server) einschränken?
- 24. TcpClient Ausnahme Deadlock
- 25. Wie man Zahlen in einem Textfeld mit jquery einschränken kann
- 26. Wie lege ich einen Fortschrittsbalken für jquery Datei-Upload-Plugin?
- 27. Wie kann ich den Dateityp im Dateisuchmenü eines AsyncFileUpload im ASP.NET AJAX Control Toolkit einschränken?
- 28. tcpclient vs httpwebrequest
- 29. Machen Sie einen Unterschied zwischen einem TcpClient in C#
- 30. einschränken UIPageViewController (mit TransitionStyleScroll) pan Geste auf einen bestimmten Bereich
Hmm, leider ist mein Server auf dem LAMP-Stack, damit BITS nicht funktioniert. Gut zu wissen aber. – Luke