100分求解:如何实现完成端口/重叠IO模型下的Socket精确发送或接收限速?

时间:2021-11-11 23:51:39
不用QoS等依赖性强的特性,不需要另一端的通讯配合,如何实现精确限速?
所谓精确限速就是例如:
发送限速:像ServU的限速100K/s,Ftp客户端下载速度一直保持在100K/s而不会时高时低
接收限速:FlashGet限速100K/s下载ServU的文件,ServU方会显示流量为 100K/s

总而言之就是这个速度不需要与连接的另一方协调,只是自己限制自己一方的速度,并且在对方看起来这个速度是十分稳定的,不会出现偏移很大的情况(例如服务器限速100K/s户端不能显示时而80K/s而120K/s)。

有人叫说参考滑动窗口算法,但是那个必须两边配合,对于普通的HTTP/FTP这类高层的应用协议没有什么地方可以放窗口大小通告字段。

见过很多方法都是说用Sleep,但是对于完成端口不是每个连接一个线程,这个方法并不适用,至少我不会。还有就是完成端口是数据到达再通知,而不是主动recv,那“使用延时recv来限制下载速度”行不通了。

9 个解决方案

#1


你说一直速度保持在100KB/S,那要在安装了Serv-U的那台系统的带宽比较稳定,以及下载的那台系统的带宽也相对稳定才会实现的.下载的速度就算限制在100KB/S,但服务器的带宽突然出现问题,或者正在下载的客户的网络出现点问题,也会影响这个速度,所以你所说的,过于理想化,就算程序能做到完美的限速,但受到网络的问题所影响,也不会做到100%准确的.

上面的只是题外话,你主要还是想问如何在IOCP模型中限制发送或接入速度.IOCP模型的服务器软件中限速我是没做过,不过在WSAAsyncSelect异步模式的FTP服务器程序我是写过,在IOCP模型中应该也是适用的.我使用的Timer.由于程序兼容于所有win系统,所以在win 9x/ME中使用的
Standard Win32 Timer(MFC程序中最常见的WM_TIMER).在NT系统中,我使用的是Queue timer(CreateTimerQueueTimer(),DeleteTimerQueueTimer()等API的调用,它本身是个回调.在IOCP模型中,只能是用Queue Timer了.Timer的作用在于,在异步情况下,可以让你延迟一定时间后,再执行某些操作(例如send(),recv()或其它).至于如何实现,视乎你自己如何写代码,因为限制速度这些功能,并没有一个标准(除非是QoS,但QoS太依赖很多系统服务了,所以在市场中会做限速的异步服务器软件,没看到过哪个会用QoS的),每个软件的限制方法都不一样.

#2


完全恒速是不可能的,也是没有意义的.
粗略些也可以,你一定有方法.

#3


基本上这个很难

#4


关键是限速有什么意义?
非要100K,网慢点90K又有什么影响?

#5


限速的意义在于,如果你的带宽是1000 KB,你不想你的FTP服务被一个用户下载就用光,那只能限制用户的下载速度,这样才能保证其它用户也可以享受到一定的速度下载.

#6


那暂时撇开速度恒定不说,IOCP/Overlapped IO怎样达到限速的功能?
速度不可能十分恒定那是当然得了
但是也总不能一下50一下飙到150那么恶心吧。。servu方的限速在ftp客户端看来是比较恒稳的。

#7


关注。

我理解楼主限速的意思是限制最高速度,至于因为网速问题导致速度低于最高速度,这个应该是不关心的。

#8


我就是楼上的那个意思。
版主们能否帮忙回答一下?

#9


顶楼的如果需要的是方法或思路,我已提供,如果需要实际代码,那就无法提供了.阻蹇多线程型的模型(一个用户就开一个新线程去处理的模型),限速是很简单的,只需要用Sleep().但对于异步模型,那是复杂很多的.你可以看看网络上的服务器软件,多数只有FTP服务器或代理服务器软件是带有这种限速功能的,而且这些软件多数都是阻塞多线程模型的.有了思路和方法,只能靠自己去开发出来,毕竟异步模型的限速模块,在做外包项目里,这个功能是额外收费的,而且也能卖钱,不太可能将实际代码发给你.

#1


你说一直速度保持在100KB/S,那要在安装了Serv-U的那台系统的带宽比较稳定,以及下载的那台系统的带宽也相对稳定才会实现的.下载的速度就算限制在100KB/S,但服务器的带宽突然出现问题,或者正在下载的客户的网络出现点问题,也会影响这个速度,所以你所说的,过于理想化,就算程序能做到完美的限速,但受到网络的问题所影响,也不会做到100%准确的.

上面的只是题外话,你主要还是想问如何在IOCP模型中限制发送或接入速度.IOCP模型的服务器软件中限速我是没做过,不过在WSAAsyncSelect异步模式的FTP服务器程序我是写过,在IOCP模型中应该也是适用的.我使用的Timer.由于程序兼容于所有win系统,所以在win 9x/ME中使用的
Standard Win32 Timer(MFC程序中最常见的WM_TIMER).在NT系统中,我使用的是Queue timer(CreateTimerQueueTimer(),DeleteTimerQueueTimer()等API的调用,它本身是个回调.在IOCP模型中,只能是用Queue Timer了.Timer的作用在于,在异步情况下,可以让你延迟一定时间后,再执行某些操作(例如send(),recv()或其它).至于如何实现,视乎你自己如何写代码,因为限制速度这些功能,并没有一个标准(除非是QoS,但QoS太依赖很多系统服务了,所以在市场中会做限速的异步服务器软件,没看到过哪个会用QoS的),每个软件的限制方法都不一样.

#2


完全恒速是不可能的,也是没有意义的.
粗略些也可以,你一定有方法.

#3


基本上这个很难

#4


关键是限速有什么意义?
非要100K,网慢点90K又有什么影响?

#5


限速的意义在于,如果你的带宽是1000 KB,你不想你的FTP服务被一个用户下载就用光,那只能限制用户的下载速度,这样才能保证其它用户也可以享受到一定的速度下载.

#6


那暂时撇开速度恒定不说,IOCP/Overlapped IO怎样达到限速的功能?
速度不可能十分恒定那是当然得了
但是也总不能一下50一下飙到150那么恶心吧。。servu方的限速在ftp客户端看来是比较恒稳的。

#7


关注。

我理解楼主限速的意思是限制最高速度,至于因为网速问题导致速度低于最高速度,这个应该是不关心的。

#8


我就是楼上的那个意思。
版主们能否帮忙回答一下?

#9


顶楼的如果需要的是方法或思路,我已提供,如果需要实际代码,那就无法提供了.阻蹇多线程型的模型(一个用户就开一个新线程去处理的模型),限速是很简单的,只需要用Sleep().但对于异步模型,那是复杂很多的.你可以看看网络上的服务器软件,多数只有FTP服务器或代理服务器软件是带有这种限速功能的,而且这些软件多数都是阻塞多线程模型的.有了思路和方法,只能靠自己去开发出来,毕竟异步模型的限速模块,在做外包项目里,这个功能是额外收费的,而且也能卖钱,不太可能将实际代码发给你.