Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用TcpClient对上载进行分级限制?_C#_.net_Tcp_System.net - Fatal编程技术网

C# 如何使用TcpClient对上载进行分级限制?

C# 如何使用TcpClient对上载进行分级限制?,c#,.net,tcp,system.net,C#,.net,Tcp,System.net,我正在编写一个实用程序,将上传一堆文件,并希望提供选项,以限制上传率。使用TcpClient类时,限制上传速率的最佳方法是什么?我的第一反应是每次使用有限的字节数调用NetworkStream.Write(),在上传缓冲区之前,在调用之间休眠(如果流尚未完成写入,则跳过调用)。有人以前实现过这样的事情吗?< /p> < p>而不是创建这个,您可能还需要考虑位(后台Internet传输服务),它允许用户(或管理员)配置带宽,并处理传输的排队。 它确实需要服务器上的特定支持(包括在IIS中,但需要启

我正在编写一个实用程序,将上传一堆文件,并希望提供选项,以限制上传率。使用TcpClient类时,限制上传速率的最佳方法是什么?我的第一反应是每次使用有限的字节数调用NetworkStream.Write(),在上传缓冲区之前,在调用之间休眠(如果流尚未完成写入,则跳过调用)。有人以前实现过这样的事情吗?< /p> < p>而不是创建这个,您可能还需要考虑位(后台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();

这是一个未经测试的代码草案,但我认为它足以理解主要思想。

我知道这是一个古老的条目,但我认为这些信息对通过谷歌或其他网络搜索获得的人非常有用

如果我们使用“仲裁器”发布的解决方案,我们会发现线程将发送大量数据,然后它将休眠很长时间,因为通常速度限制超过每秒32到200 kb,而使用standar pc时,线程每秒可以管理超过10到100 MB的数据

我在我的项目中使用了下一个解决方案。请注意,这只是一段代码,您必须修改它以适应自己的需要。它是用visualbasic编写的。顺便说一句,对不起我的英语

    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()
Dim SpeedLimit的长度=User.DownloadKbSpeedLimit*1024,经过的时间长度=0
'尝试根据操作系统调整缓冲区大小。
看起来很愚蠢,但测试表明这样做会更好。
如果Environment.is64位OperatingSystem,则
stream.BufferSize=64*1024
其他的
stream.BufferSize=32*1024
如果结束
'如果buffersize大于speedlimite,请减少buffersize以避免发送太多数据
如果SpeedLimit>0且e.BufferSize>SpeedLimit,则e.BufferSize=SpeedLimit
'创建字节数组以发送数据
作为字节的Dim缓冲区(如BufferSize)
'创建手表以控制速度
Dim传输为整数=0,手表为新秒表()
看,开始
'开始发送数据
虽然是真的
'这使程序能够控制其他事件或线程
系统线程线程睡眠(10)
Windows.Forms.Application.DoEvents()
'恢复数据并写入流
如果SpeedLimit=0或传输的速度小于SpeedLimit,则
读取为整数的Dim=SomeFileStream.Read(缓冲区,0,缓冲区.Length)
如果读取值为0,则在
Stream.Write(缓冲区,已读)
已传输+=已读取
如果结束
如果Watch.elapsedmillesons>1秒,则
传输=0
Watch.Restart()
如果结束
结束时
看,停
Stream.Close():Stream.Dispose()
希望这能帮助任何人。
再见。

我对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
节流网络Mbps。。。 带宽UsedThisSecond=session.bytesSentThisSecond+session.ByTesReceivedThisSecond 如果现在bandwidthTimer.add毫秒(50)>且带宽使用秒数>=(Mbps/20),则 而bandwidthTimer.addMillimes(50)>现在 线程。睡眠(1) 结束时 如果结束
如果bandwidthTimer.addMillimes(50)Hmm,不幸的是,我的服务器在LAMP堆栈上,所以位无法工作。很高兴知道。谢谢你的意见。尽管这是一个老话题,但该活动会引起注意:)我想您需要一个手表。请在那里重新启动,因为这样会将经过的时间重置为0,然后重新启动计时器。watch.reset只是将时间设置回0并停止itmer