![]() | 1 ss098 2014-10-31 17:25:25 +08:00 via Android 浏览器客户端向服务器发送数据应该不可以限制,但服务器可以限制下载速度,因为发送多少数据是由服务器决定的,但客户端即浏览器发送数据到服务器时倘若服务器限度,但实际上已经有网络数据到达服务器,所以限制是没有用的。 个人理解,若有纰漏,欢迎指正。 |
![]() | 2 zhengkai 2014-10-31 17:34:54 +08:00 为什么要限制上传……这需求太奇怪了 可以在 nginx 上设定限速(limit_req) |
![]() | 4 mengskysama 2014-11-01 00:16:16 +08:00 ![]() |
![]() | 5 ss098 2014-11-01 00:23:16 +08:00 |
![]() | 6 ryd994 2014-11-01 10:50:18 +08:00 via Android 还有就是TCP窗口小一点 |
![]() | 7 ryd994 2014-11-01 10:53:49 +08:00 via Android @mengskysama 如果稳定的加上一个延迟的话,TCP完全能够处理,延迟大不是问题,随机性才是 |
![]() | 8 ryd994 2014-11-01 11:04:31 +08:00 via Android @mengskysama 事实上就是让客户重发,但是别忘了TCP是有拥塞算法的,重发之后就会降速。也就是说给客户端一个拥塞的假象 |
![]() | 9 ryd994 2014-11-01 11:10:33 +08:00 via Android @mengskysama 缺德一点也可以不改协议层,ipfilter 限制频率drop就行 |
![]() | 10 mengskysama 2014-11-01 12:37:01 +08:00 @ryd994 我没有见到一个软件是这样做的,nginx,libtorrent,transmission等等。您不觉得这是用大炮打鸟吗,我要维持一个速度岂不是要不断丢包?明显不是这样做的。如果在win下面动协议层至少需要ndis,没有软件带这么玩的吧。 |
![]() | 11 ryd994 2014-11-01 17:08:18 +08:00 @mengskysama 丢包只会drop开始那一段超速的,然后客户端的拥塞算法就会认为网络上发生拥塞,发送速度就下来了,然后后面就会一稳定在这个速率上,既然不超速就不会发生drop。所以尽管浪费了开头那段,但是后面的包是完全没影响的。这只是在无法修改服务器代码时的一种workaround而已。 更文明的办法是调整窗口大小。ack会带上window size。这就是正规的flow control: http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Flow_control 你说的控制读socket本质上就是这个,没读走的数据还留在系统缓冲区里,然后ack回去的window size就小了,发送方就会控制速度了。这部分都是系统tcp栈做好的轮子。 如果自己写服务器的话,确实这样做才是正解。 如果写的只是应用的话就该查http服务器的文档。 @zhengkai 你说的limit_req是限制请求频率而非传输速率。应当使用upload_limit_rate: http://wiki.nginx.org/HttpUploadModule#upload_limit_rate |
![]() | 12 mengskysama 2014-11-01 17:46:14 +08:00 @ryd994 第一个TCP拥塞算法里只有遇到丢包才会减小窗口对吧?意味着后面我要不断丢包来保持速度,您觉得合理吗? 第二个,窗口大小和缓冲区大小没有直接联系,窗口大小是拥塞算法给的,这是种特例,就是BUF<CWND |
![]() | 13 ryd994 2014-11-01 18:05:58 +08:00 @mengskysama …………正常的连接也是不停地拥塞,减速,拥塞,减速好吧…………也就是说本来硬件丢掉的,现在软件丢掉而已,是等效的。不是说合不合理,而是说这是你无法控制代码时的唯一方法。 窗口大小不只是拥塞算法给,也会由接收方在ACK中指定,这就叫flow control啊…… http://www.tcpipguide.com/free/t_TCPWindowSizeAdjustmentandFlowControl-2.htm 缓冲区里的数据会减少ack回去的window size,这就是你之前说的方法的实际过程啊,您是不是在4层待太久了,有空也该来三层看看啊。 |
![]() | 14 mengskysama 2014-11-01 18:20:47 +08:00 @ryd994 一般丢包发生在信道比较窄的时候,你用400K信道传输40K基本上不会丢包。 |
![]() | 15 ryd994 2014-11-01 18:24:33 +08:00 @mengskysama 那前提是你只有这点发送啊……如果不额外指定,发送方有什么理由不用满带宽呢? |
![]() | 16 ryd994 2014-11-01 18:25:29 +08:00 @mengskysama 传输设备hold不住的时候就会扔掉啊 |
![]() | 17 mengskysama 2014-11-01 18:26:20 +08:00 @ryd994 你说的由接收方在ACK中指定,接收方在ACK中指定没错的,但是接收方怎么确定这个大小的,就是通过拥塞算法。 http://baike.baidu.com/view/4521733.htm?fr=aladdin |
![]() | 18 mengskysama 2014-11-01 18:27:58 +08:00 @ryd994 po主要的就是限速啊,如果在理论完美的链路上限速20K,还要不断靠丢包来达到效果我认为不合适吧、 |
![]() | 19 mengskysama 2014-11-01 18:31:25 +08:00 反正不管怎么说都是减小cwnd就对了。 |
![]() | 20 mengskysama 2014-11-01 18:31:45 +08:00 这点上我们2说的是一样的。 |
21 JackWindows 2014-11-02 01:45:17 +08:00 via iPhone @mengskysama 绝对不是一回事。tcp只是两端window一样而已,发送速率由sender控制,receiver只能通过rfc协定,采用丢包或者ECN(explicity congestion notification)来限制发送方的速率。而且发送端的tcp stack实现可以无节操一点,override rfc协议标准。所以通过服务器端限速绝对是浪费带宽的行为,正常做法是由前端的程序实现限速。 |
![]() | 22 mengskysama 2014-11-02 03:39:31 +08:00 ![]() @JackWindows 我认同你的观点,我说的一回事是指下载和上传,只是数据流方向不一样,所以不存在下行速度能限制上行速度不能限制的问题。 |