TCP/IP 的流量如何控制?

1 控制数据包大小,需要在三次握手时确定。控制该值可以精确流量控制,好比答应每次发送的数据包最大是3000Bytes,这个值取决于接收方和发送方的网路MTU,理论值是65536bytes = 64k, 这个值设置在流量控制值的1.5倍左右有利于精确地流量控制。

2 控制发送方的 梗阻窗口,梗阻窗口表示答应发送方一次连续发送多大的数据,假如这个值是 30k, 且答应每次发送的数据包的最大长度是1K,那表示发送方可以连续发送30个数据包再等接收方的ACK应答。梗阻窗口是动态变化的,当知足一定前提时发送方就会自动调整该窗口的大小,好比在建立三次握手的时候,会通过“慢启动算法”来确定该值,在传输数据时,当发现收到很多相同的应答包时,或者确认接收方应答包超时的时候,发送方就会调整该窗口了,这个窗口在流量控制上的意义:好比我们流量控制时5K/S,但发送方一次是发送30K的数据,表示当我们收到5K的数据时,进入流量控制,那接下来网络中可能还有一些数据包在传输,假如这些数据包丢掉的话会占用少些带宽,假如继承被我们接收的话可能影响流量控制的精确性。接收方可以通过延迟ACK包的发送,或者直接丢包来使发送方动态修改梗阻窗口。

3 要流量控制时,
1)发送一个WIN = 0的ACK包,丢掉最后收到的包,接下来每收到的包都丢掉并发一个ACK应答包
2)发送一个WIN = 0的ACK包,接收最后收到的包,接下来每收到的包都接收并发一个ACK应答包,WIN = 0
丢包会铺张带宽,这样的流量控制显然意义不大,所以采用方案2),这样可能会降低流量控制的精确性,但也避免带宽的铺张。

4 进入流量控制的时候,还答应系统发送ACK应答包吗?
系统在俩种情况下会发送ACK应答包
1) 当接收缓存为0时,这时候应该通知发送方,让发送方休止发送数据包以免梗阻网络,由于接收窗口为0时表示主机暂时没有更多的缓冲区来处理来自网络的数据包
2)从收到第一个数据包开始,每隔200毫秒都会发送一个ACK应答包,当然通过系统设置来改变发送ACK应答包的频率。200毫秒这个值可以通过注册表值TcpDelAckTicks 来修改,但一般建议不要大于500毫秒。(适合2000 SP3 系统)。2000以上系统:TcpAckFrequency,n表示200毫秒内每收到n个包都发送一个ACK应答包。好比n = 4 表示在200毫秒内,每收到4个数据包都应该发一个ACK应答包。路径是HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\<Interface GUID>
当进入流量控制的时候,后续收到的包都会让系统处理,系统也会发送ACK应答包,所以我们必需进行拦截,保证在流量控制模式下,ACK的发送只由我们来处理。得保证发送的每个ACK包的WIN值都是0。