下载  >  网络技术  >  网络基础  > TCP 的那些事儿 【带书签高清PDF版】

TCP 的那些事儿 【带书签高清PDF版】 评分:

无论是PC客户端开发还是移动开发,或是Web开发, 网络编程都是很重要的一块, 深入理解TCP/IP和HTTP协议是一个优秀程序员的必备技能。
protocols and scalable client server systems 关于 IME WATT数量太多。从上的的描术划道, TIME WAIT.是个很要的状态,但如冥在大并发的短链妾下, TIME WAIT就会太多,这也会消耗很多系统原。只要搜一 下,你就会发现,十有八九的理方式都是教你没置两个参数,一个叫 tcp_tw_reuse,另一个叫 tcp_tw_recyde的参数,这两个参被关矛的,后者ecye比前者 Resue更 为进,resu要桑些另外,如果使 tcp_tw_reuse,必需设置 tcp_ timestamps=1,似效这里,你定要主,打开这两个参数会有比较大的坑—可能会让TcP 连接出一些诡异的向题(因为如上述样,如果不等待超重用的话,新的连能会建不上正如官方文档上的样" t should not be changed without advice/request of technical experts") 关于 top_ tw_reuse。官方文档上说 cp_tw_reuse加上 -tcp- timestamps(又叫PAW, for Protection Against Wrapped Sequence Numbers)可以议的角度上的安全,但是你需 要 ptimestam在为都开(你可以读下 rcn task unique的親码).我个人估计还是有—些场景会有问题。 关于 tcp tw_recycle.如果是 tcp_tw_recycle开了话,会假设对端启了 tcp__timestamps,然后会太比戳,如剿翟大了就可煇用但是,如职是一个A啊网 纟的话如:一个公司个P出公网)或对P被弓台重用了,这个事尕了。建链夠SYN冋能就被接去掉了(你可能会看 connection time ou的锚误)(如你 想双擎一凡inu的內代,请看源 tcp timawait state process)。 关于 cp_max tw_buckets.。这个是肼发的TMWA的量,默人值是180000如果超限,那么,系会把纶 destory掉,然在日忐里」个警(如; time wait bucket ble overflow),官网文裆兑文个爹数是用来υυoS攻击的邙默80000不小这个还是需要瘧实阿兄考虑。 Again,使用 tcp_tw_reuse和 Itcp_tw_recycle.来解决 IME WA的问是非常常危险的,因为这两个参数反了TCP协议(RFC1122) 其实, ME WAIL表示的是你主动断连接,所以,这就是所谓的“不作死不会死“。试想,如果让对端断连接,那么这个破问题就是对方的了,吗呵。另外,如 果你的服务器是于HTTP服务器,那么设置一个HTTP的KeepAlive有多重要(浏览器会重用一个ICP连接来处理多个HTP请求)然后让客户端去断链接(你要 小心,浏览器可能会非常贪婪,他们不到万不得已不会主动断连接)。 据传输中的 Sequence Number 下图是我人 Wireshark中截了个我在访问 coolshell.cn时的有数据传输的图给你看一下, SeqNum是怎么变的。(使用 Wireshark菜单中的 Statistics->FloW Graph 192.1681192 13.45.3.16f Comment SYN Seq =0 Scg-0Ack -1 1c33 ACK 299LAk-1 品3 5u4-4121ALk-1 ACK 5e=1Ak=4321 s=n=14rk=631 HAckene seg=lAck=b318 ACK 你可以看到, Seqnum的增加是和传输的字节数相关的。上图中,三次握手后,来了两个Len:1440的包,而第二个包的 SeqNum就成了1441.然后第一个ACK 回的是1441,表示第一个1440收到了 注意:如果你用 Wireshark抓包程序看次握手,你会发现5qNum总是为0,不是这样的, Wireshark为了显示更友好,使用了 Relative SeqNum相对序 号,你只要在右键菜单中的 protocol preference中取消掉就可以看到“ Absolute SeqNum"了 TCP重传机制 TCP要保证所有的数据包都可以到达,所以,必需要有重传机制。 注意,接收端给发送端的Ak确认只会确认最后一个连续的包,比如,发送端发了1,2,34.5一共五份数据,接收端收到了1,2,于是回ack3,然后收到了4(注 意此时3没收到),此时的TCP会怎么办?我们要知道,因为正如前面所说的, SeqNum和Ack是以字节数为单位,所以ack的时候,不能跳着确认,只能确认最 大的连续收到的包,不然,发送端就以为之前的都收到了 超时重传机制 一种是不回ack,死等3,当发送方发现收不到3的ak超时后,会重传3.一旦接收方收到3后,会ack回4意味着3和4都收到了 但是,这种方式会有比较严重的问题,那就是因为要死等3,所以会导致4和5即便已经收到了,而发送方也完全不知道发生了什么事,因为没有收到Ack,所以 发送方可能会悲观地认为也去了,所以有可能也会导致4和5的車传。 对此有两种选择 是便重 timeout的包。也第份数据。 另种是重传 timed后所有的,世是第3,4,5这三价数据。 这两种方式有好也有不好。第一种会节省宽,但是慢,第二种会快一点,但是会浪费带宽,也可能会有无用功。但总体来说都不好。因为都在等 timeout, timeou可能会很长(在下篇会说TCP是怎么动态地计算出 timeout的 快速重传机制 于是,TCP引入了一种叫 Fast Retransmit的算法,不以时间驱动,而以数据驱动重传。也就是说,如果,包没有连续到达,就ack最后那个可能被丢了的包 如果发送方连续收到3次相同的ack,就亘传。 Fast Retransmit的好处是不用等 tImeout了再重传。 比如:如果发送方发出了1,2,3,4,5份数据,第一份先到送了,于是就ack回2,结果2因为某些原因没收到,3到达了,于是还是ack回2,后面的4和5都到 了,但是还是ack回2,因为2还是没有收到,于是发送端收到了三个ack=2的确认,知道了2还没有到,于是就马上重转2。然后,接收端收到了2,此时因为 ,4,5都收到了,于是ack回6。示意图如下 ACK 2 ACK 2 ACK 2 ACK 6 ender Receiver Fast retransmit只解决了—个问题,就是 timeout的问题,它依然面临一个艰难的选择,就是重转之前的一个还是重装所有的问题。对于上面的示例来说,是重 传#2呢还是重传#2,#3,#4,#5呢?因为发送端并不清楚这连续的3个ak(2)是谁传回来的?也许发送端发了20份数据,是#6,#10,#20传来的呢。这样,发 送端很有可能要重传从2到20的这堆数据(这就是某些TCP的实际的实现)。可见,这是一把双刃剑。 SAcK方法 另外一种更好的方式叫: Selective Acknowledgment(sACK(参看RFC2018),这种方式需要在ICP头里加一个SACK的东西,ACK还是 Fast retransmit 的ACK,SACK则是汇报收到的数据碎版。参看下图 接收缓洲区 ACK. 300 5006 ACK 300 SACK 500-700 ACK300.SACK900-1100.500-700 这样,在发送端就可以根据回传的SACK来知道哪些数据到了,哪些没有到。于是就优化了 Fast Retransmit的算沄。当然,这个协议需要两边都支持。在 Linux 下,可以通过 tcp_sack参数打开这个功能( Linux2.4后默认打开), 这里还需要注意一个问题—接收方 Reneging,所胃 Reneging的意思就是接收有权把已经报给发送端sACK里的数据给丟了。这样干是不被鼓励的,因为这 个事会把问题复杂化了,但是,接收方这么做可能会有些极端情况,比如要把内存给别的更重要的东西。所以,发送方也不能完全依赖SACK,还是要依赖 AcK,并维护 Time-Out,如果后续的ACK没有增长,那么还是要把SACK的东西重传,另外,接收端这边永远不能把SACK的包标记为Ack。 注意:SACK会消费发送方的资源,试想,如果一个攻击者给数据发送方发一堆SACK的选项,这会导致发送方开始要重传甚至遍历已经发出的数据,这会消耗很 多发送端的资源。详细的东西请参看《 TCP SACK的性能权衡》 Duplicate SACK-重复收到数据的问题 Duplicate SACK又称D-SACK,其主要使用了SACK来告诉发方有吲烂数据被重复授收了.RF-283里有详细描述和示例。下面举几个例子(来源于RFC D-SACK使用了SACK的第一个段来做标志, 如果SACK的第个的围ACK所覆盖,那么就是D-SACK 如果SACK的第个的被SACK的第二个段霍盖,那么就是 D-SACK 示例:ACK丢包 下面的示例中,去了两个ACK,所以,发送端重传了第一个数据包(3000-3499),于是接收端发现重复收到,于是回了一个SACK=3000-3500,因为ACK都到 了4000意味着收到了4000之前的所有数据,所以这个SACK就是 D-SACK—旨在告诉发送端我收到了重复的数据,而且我们的发送端还知道,数据包没有丢, 天的是ACK包。 Transmitted Rcccivcd ACK Scnt Segment cement (Inclucirg SACK Blocks) 3000-3499 3000-349 9 3500 (ACK droppe 3500-3999 350039994C00AC3 dropped)30003499 000-3499000-34394000,SACK=300 示例二 延误 下面的示例中,网络包(1000-1499)被网络给延误了,导致发送方没有收到ACK,而后面到达的三个包触发了“ Fast retransm算法”,所以重传,但重传 时,被延误的包又到了,所以,回了一个SACK=1000-1500,因为ACK已到了3000,所以,这个SACK是 D-SACK—标识收到了重复的包。 这个案例下,发送端知道之前因为“ Fast retransm算法”触发的重传不是因为发出去的包丢了,也不是因为回应的ACK包丢了,而是因为网络廷时了。 Transmitted Received ACK sent Segment Segment (Inc⊥ ading SACK E⊥ocxs) 5C0-999 530-999 1000 00C-1499 delayed 150-1999 1500-19991000,SACx=1500-2C00 2000-2499 20C0-2499-000,SACK=1500-2500 500-2999 2500-239910c0,sACK=1500-3000 100 0-1499 1000-14993300 10C0-1499300c,SACK=1000-1500 可见,引入了 D-SACK,有这么几个好处 1)可以让发送方知道,是发出去的包丢了,还是回来的ACK包丢了。 )是不是自己的 timeout太小了,导致重传。 3)网络上出现了先发的包后到的情况(又称 reordering) 4)网络上是不是把我的数据包给复制了。 知道这些东西可以很好得帮助TcP了解网绉情况,从而可以更好的做网络上的流控 Linux下的 tcp dsack参数用于开启这个功能(Lnux2.4后默认打开 TcP的RTT算法 从前面的TCP重传机制我们知道 Timeout的设置对于重传非常重要 设长了,重慢,丟了半对才載发,没有率,性前差; 设短了,会导致可并有丢就渾发。于是重发的快,会曾网络拥塞,导致更多的旋时,更多的致更多的重发。 而且,这个超时时间在不同的网络的情况下,根本没有办法设置一个死的值。只能动态地设置。为了动态地没置,ICP引入了 RTT--Round Trip Time,也就 是一个数据包从发出去到回来的时间。这样发送端就大约知道需要多少的时间,从而可以方便地设酱 Timeout--RTO( Retransmission Time out),以让我们 的重传机制更高效。听起来似乎很简单,好像就是在发送端发包时记下t0,然后接收端再把这个ack回来时再记一个t1,于是RTT=t1-t0。没那么简单,这只 是一个采样,不能代表普遍情况 RFC793中定义的经典算法是这样的 1)首先,先采样RTT,记下最近好几次的RTT值 2)然后做平滑计算SRTT( Smoothed rtt),公式为:(其中的a取值在08到0.9之间,这个算法英文叫 Exponential weighted moving average,中 文叫:加权移动平均) SRTT =(a* SRTT)+((1-a)*RTD 3)开始计算RTO。公式如下 RTO min[ UBOUND, max I LBOUND,(*SRTT)] I 其中 UBOUND是最大的 timeout时间,上限值 LBOUND是最小的me时间,下限直 β值般在13到20之间 Karn/ Partridge算法 但是上面的这个算法在重传的时候会出有一个终极问题——你是用第一次发数据的时问和ack回来的时问做RT样本值,还是用重传的时间和ACK回来的时间做 RTT样本值? 这个问题无论你选那头都是按下葫芦起了瓢。如下图所示 况(a是ack米,所传。如果你计算第次发送和ACK的时间,那么,玥算大了。 情兄(b)是ck來慢了,但是导致了重传,仨刚重传亻会儿;之前^〈民了。如果你弇重传的时AK回來的的差,就会弇短∫ Sender Receiver Sender Receiver 2/ 上 RetransmIssion K ACr (a) 所以1987年的时候,搞了一个叫Karn/ Partridge Algorithn,这个算法的最大特点是—忽略重传,不把重传的RT做釆样(你看,你不需要去解决不存在的 但是,这样一来,又会引发一个大BUG如果在某一时间,网络闪动,突然变慢了,产生了比较大的延时,这个延时导致要重转有的包(因为之前的RTO很 小),于是,因为重转的不算,所以,RTO就不会被更新,这是一个灾难。于是Karn算法用了一个取巧的方式—只要一发生重传,就对现有的RTO值翻倍 (这就是所谓的 Exponential backoff),很明显,这种死规矩对于一个需要估计比较准确的RTT也不靠谱。 Jacobson/ Karels算法 前面两种算法用的都是“加权移动平均”,这种方法最大的毛病就是如耒RT有一个大的波动的话,很难被发现,因为被平滑掉了。所以,1988年,又有人推出 来了一个新的算法,这个算法叫 Jacobson/ Karels Algorithm(参看RFC6289)。这个算法引入了最新的RTT的采样和平滑过的SRTT的差百做因子来计算。公 式如下:(其中的 Devrtt是 Deviation rtt的意思) sRTT=SRTT+a(RTT-SRT—计算平滑RT DevRTT=(1阝) DeVRTT+β(RTT5RT)—计算平滑RT和真实的差距(加权移动平均) RTo=u*sRT+ d*DevOT—神一样的公式 (其中:在 Linux下,a=0.125,阝=0.25,p=1,d=4这就是算法中的“调得一手好参数”, nobody knows why, it just works.)最后的这个算法 在被用在今天的TCP协议中( Linux的源代码在: tcp rtt estimator)。 TCP滑动窗口 需要说明一下,如果你不了解TCP的滑动窗口这个事,你等于不了解TCP协议。我们都知道,TCP必需要解决的可靠传输以及包乱序( reordering)的呵题,所 以,TCP必需要知道网络实际的数据处埋带宽或是数据处埋速度,这样才不会引起网络捐塞,导致丟包。 所以,TCP引入了一些技术和设计来做网络流控, Sliding Window是其中一个技术。前面我们说过,TCP头里有一个字段叫 Window,又叫 Advertised Window,这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以裉据迒个接收端的处理能力来发送数据,而不会导致接收端处理 不过来。为了说明滑动窗口,我们需妻先看一下TCP缓冲区的一些数据结构 发送端程序 接收端程序 TCP Lastsyte Writter Last ByteRe LastByte Acked Lasteyte Sent astByteRcvd 上图中,我们可以看到 擦端 astByteReady了TC区中到的位置, NextByteExpectec向的方是的迫续包的最后个位置, LastByteRcved的是收至的包的最后个位置,我们冋以看到 有些数不殳有到,所以有数居空白区。 发诺的 astByteAckec向了被端A的位置(表功发送), LastByteSen示发出去了,殳有收到成功确人的Ack, LastByteWritten指$上层应用在写的地 于是 按收端在给发送端回ACK中会汇报彐彐的 Advertisedwindow= MaxRcy Buffer- Last ByteRcvd-1 而友送方会根文个安口来控制发送数居大小,以吳收方可以卜理。 下面我们来看一下发送方的滑动口示意图 Window Al eady Send Window Usable Window Left edge of Sent (14 bytes) (20 bytes) 6 bytes) Right Edge of Send wine。W Send window 國回时回州叫四四回四回… Category #1 category t2 cate gory t3 Category ft4 Cent ard Sent But Not Yet Acknowledged Not sent Not sent, Recip ent ACKnowledged (Scnt and Still Outstanding) Recipient Ready Not Ready Io Recerve (31 bytes) To Receive (44 bytes) (图片来源) 上图中分成了四个部分,分别是:(其中那个黑模型就是滑动窗口) 1已攻型ack确认的数据。 #2发还义ack的 #3在窗口中还有发出的(接收方还有空间) #窗口心外的数据(接收方没空间) 下面是个滑动后的示意图(收到36的ack,并发出了46-51的字节) Send window New Usable indcw Posiion) (Slides 5 Bytes To The Right) Window 回四四叫叫叫四呵回可四回吗四同 Categ。ry#1 Category #2 Category #3 Cat#4 下面我们来看一个接受端控制发送端的图示 client server ShD, UNA-1 RCV.VND =350 RCV.NXT=1 1. Send 140-Byte Request SND UNA=1 eq Num= 2. Receive Request; send Ack, Arknmwradgmant Reduce Window By 100 岛rkMm=1:41 WIndoW= 261 RCWWND= 250 Reduce send Window to 260 14 SVD. UNA=141 SND WND= 260 SNO,NDXT-141 4. Send 180-Byte Request Request LEngth-180 MD UNA-141 SNDWND= 260 Usable-00 5. Receive Request; send Ack, Acknowledgment Reduce Window By 180 ND MXU 311 Window= 80 RCV. WND= 80 G Reduce Send Window to 80 14 SND.WHD-80 5ND UNA=321 Usable RCU.NXT-J21 SND NXT-J21 7. send 80-Byte Request Length-00 ND.- 90 Sey tlurrI321 B Receive Requcst; Send AcK, 140‖10 w By 80(to a Windo=0 RCV. NQ=0 9. Reduce send window to b 441800 SNDLND= 0 Usable- RCV. NKT-401 (图片来源) Zero window 上图,我们可以看到一个处理缓慢的 Server(接收端)是怎么把 Client(发送端)的 ICP Sliding Window给降成0的。此时,你一定会问,如果Wind。w变成0 了,TCP会怎么样?是不是发送端就不发数据了?是的,发送端就不发数据了,你可以想像成“ Window closed”,那你一定还会问,如果发送端不发数据了, 接收方一会儿 Window size可用了,怎么通知发送端呢? 解决这个问题,TCP使用了 Zero Win dow probe技术,缩写为zWP,就是说,发送端在囱口变成0后,会发ZWP的包给接收方,让接收方来ack他的 Window 尺寸,一般这个值会设置成3次,第次大约30-60秒(不同的实现可能会不一样)。如果3次过后还是0的话,有的TCP实现就会发RST把链接断了 注意:只要有等待的地方都可能出现DDoS攻击,ZeroWindow也不例外,一些攻击者会在和HTTP建好链发完GET请求后,就把Window设置为0,然后报务端 就只能等待进行zWwP,于是攻击者会并发大量的这样的请求,把服务器端的资源耗尽。(关于这方面的攻击,大家可以移步看一下 Wikipedia的 Sock Stress司 旁外, Wireshark中,你可以使用 gtcp analysis. zero_window来过滤包,然后使用右键卖单里的 follow TCP stream,你可以看到 Zerowindow Probe及 ZeroWindow ProbeAck的包 illy window Syndrome Silly Window Syndrome翻译成中文就是“涂安囗综合症”。正如你上面看到的一样,如果我们的接收方太忙了,来不及取走 Receive Window里的数据,那 么,就会导致发送方越来越小。到最后,如果接收方腾出几个字节并告诉发送方现在有几个字节的 window,而我们的发送方会义无反顾地发送这几个字节 要知道,我们的TCP+P头有40个字节,为了几个字节,要达上这么大的开销,这太不经济了。 另外,你需要知道网络上有个MTU,对于以太网来说,MTU是1500字节,除去TCP+IP头的40个字节,真正的数据传输可以有1460,这就是所谓的MSS(Max Segment Size)注意,TCP的RFC定义这个MSs的默认值是536,这是因为RFC791里说了任何一个P设备都得最少接收576尺寸的大小(实际上来说576是拔号 的网络的MTU,而576减去IP头的20个字节就是536)。 如果你的网络包可以塞满MTU,那么你可以用满整个带宽,如果不能,那么你就会浪费带宽。(大于MTU的包有两种结局,一种是直接被丢了,另一种是会被重 新分块打包发送)你可以想像成一个MTU就相当于一个飞机的最多可以装的人,如果这飞机里满载的话,带宽最高,如果一个飞机只运一个人的话,无疑成本增 加了,也而相当 所以, Silly Windows Syndrome这个现像就像是你本来可以坐200人的飞机里只做了一两个人。要解决这个问题也不难,就是避免对小的 window size做出响 应,直到有足够大的 window size再响应,这个思路可以同时实现在 sender和 receiver两端。 如个是由 receive端引的,我么就会使用 David d clarκs方案。在 receiver端,如果的崴据导致 window size小于某个值,可以接ackO回 sender,这样就把 window给关 闭了,也趾了 sender再发来,等到 eserver端理了-些数居后 Endows size大等于MSS,或者, receiver buffer有半空,就可把 window№J让send发关数过来。 如果这个是由 Sender端引起的,那么就会使用著名的 Nagle s algorithm。这个算的思路也是理,他有两个主要的条件(更的条件可以看下 cp nagle check函 数}:1)变到 Window size>=Mss是 Data size>=MsS,2)等衙超时200m6,这兩个条有一^凝足,他才会发数居,否在数据。 另外, Nagle算法默认是打开的,所以,对于一些需要小包场景的程序比如像tene或ssh这样的交互性比较强的程序,你需要关闭这个算法。你可以在 Socket设置 TCP NODELAY选项来关闭这个算法(关闭 Nagle算法没有全局参数,需要根据每个应用自己的特点来关闭) setsockoot(sock fd, IPPROTo cPr TCP NODELAY, (char *)&value, sizef(ir.t) 另外,网上有些文章说 TCP CORK的 socket option是也关闭 Nagle算法,这个还不够准确。 TCP CORK是禁止小包发送,而 Nagle算法没有禁止小包发送,只是 禁止了大量的小包发送。最好不要两个选项都设置。老实说,我觉得 Nagle法其实只加了个延时,没有别的什么,我觉得最好还是把他关闭,然后由自己的应 用层来控制数据,我个觉得不应该什么事都依赖内核算法。 TcP的拥处理- Congestion Handling 上面我们知道了,TCP通过 Sliding Window来做流控( Flow Contro),但是ICP觉得这还不够,因为 Sliding Window需要依赖于连接的发送端和接收端,其 并不知道网络中间发生了什么。TCP的设计者觉得,一个伟大而牛的协议仅仅做到流控并不够,因为流控只是网络模型4层以上的事,TCP的还应该更聰明地知 道整个网络上的事。 具体一点,我们知道TCP通过一个 timer采样了RTT并计算RTO,但是,如果网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,但是,重传 会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,于是,这个情况就会进入恶性循环被不断地大。试想一下,如果一个网络内有成千上万的 TCP连接都这么行事,那么马上就会形成“网络风”,TCP这个协议就会拖垮整个网络。这是一个灾难 所以,TCP不能忽略网络上发生的事情,而无脑地一个劲地重发数据,对网络造成更大的伤害。对此TCP的设计理念是:TcP不是一个自私的胁议,当拥塞发生 的时候,要做自我牺牲。就像交通阻塞一样,每个车都应该把踣让出来,而不要再去抢了。 关于拥塞控制的论文请参看《 Congestion Avoidance and Contro》(PDF) 拥塞控制主要是四个算法:1)慢后动,2)拥塞遢免,3)拥发生,4)快速恢复。这四个算法不是一天都搞出来的,这个四算法的发展经历了很多时间,到今 天都还在优化中。备注 1988年, TCP-Tahoe出了1)慢,,2)艷免,3)捕发生的快車传 190年, TCP Reno在aho础4)快速复 慢热启动算法- Slow Start 首先,我们来看一下ICP的慢热启动。慢启动的总思是,刚刚加入网络的连接,一点一点地提速,不要一上来就像那些特权车一样霸道地把路占满。新同学上高 速还是要慢一点,不妻把己经在高速上的秋序给搞乱,了。 慢启动的算法如下(cWnd全称 Congestion Window) 1)连接建好的开始先初始化cwnd=1,表明可以传一个MSS大小的数据 2)每当收到一个ACK,cwnd++;呈线性上开 3)每当过了一个RTT,cWnd=cwnd*2呈指数让升 4)还有一个 ssthresh( slow start threshold),是一个上限,当cwnd>= ssthresh时,就会进入“拥塞避免算法”(后面会说这个算法) 所以,我们可以看到,如果网很快的话,ACK也会返回得快,RTT也会短,那么,这个慢启动就一点也不慢。下图说明了这个过程 sender recelver cwnd data packct 1 RTT. ACK cwnd < cwnd 1 (for each ACK) 这里,我需要提一下的是一篇 Google的论文《 An Argument for Increasing TCP s Initial Congestion Window》Liux3.0后采用了这篇论文的建议—把 cWnd初始化成了10个MSS。而 Linux30以前,比如2.6, Linux采用了RFC3390,cwnd是跟MSS的值来变的,如果MSS<1095,则cwnd=4;如果 MSS>2190,则cwnd=2;其它情况下,则是3。 拥塞避免算法 Congestion Avoidance 前面说过,还有一个 ssthresh( slow start threshold),是一个上限,当 cwnd>= ssthresh时,就会进入“拥塞避免算法”。一般来说 ssthresh的值是65535 单位是字节,当cwnd达到这个值时后,算法如下 1)收到一个ACK时,cwnd=cwnd+1/cwnd 2)当每过一个RT时,cwnd=cwnd+1 这样就可以避兔增长过快导致网绉拥塞,慢慢的增加调整到网络的最佳值。很明显,是一个线性上升的箅法 拥塞状态时的算法 前面我们说过,当丢包的时候,会有两种情况 1)等到RTO超时,車传数据包。TCP认为这种情况太糟糕,反应也很强烈 sshthresh= cwnd/2 cwnd重置为1 进入慢后过程 2) Fast Retransmit算法,也就是在收到3个 duplicate ACKI时就开启重传,而不用等至RTO超时 TCP Tahoe的实现RTO超时。 TCP Renc的现是 sshthresh cwnd 进入快速恢复算去 Fast Recovery 上面我们可以看到RTO超时后, sshthresh会变成cwnd的一半,这意味着,如果cwnd<= sshthresh时出现的丢包,那么TCP的 sshthresh就会减了一半,然后等 cwnd又很快地以指数级增涨爬到这ˆ地方时,就会成慢慢的线性増涨。我们可以昋到,τCP是怎么通过这和强烈地震荡快逴而小心得找到网站流量的平衡点的。 快速恢复算法- Fast Recover TCP Reno 这个算法定义在RFC5681。快谏車传和快速恢复算法一般同时使用。快速恢复算汯是认为,你还有3个 Duplicated Acks说明刈络也不那么糟糕,所以没有必像 RTO超时那么强烈。注意,正如前面所说,进入 Fast Recovery之前,cwnd和 sshthresh已被更新 nd cwnd /2 sshthresh= cwnd 然后,真正的 Fast Recovery算法如下 cwnd- sshthresh+3*MSs(3的意思是确有3个数包被收到了) 重传 Duplicated ACK指知的包 如果用收到 duplicated Acks,那么cwnd-cwnd+1 如果收到了的^ck,〗么,cwnd= sshthresh,然后就入了拥塞避免的算法了。 如果你仔细思考一下上面的这个算法,你就会知道,上面这个算法也有阿题,混—它依赖于3个重复的Acks。注意,3个重复的Acks并不代表只丢了一个 数据包,很有可能是去了好多包。但这个算法只会重传一个,而下的那些包只能等到RTO超时,于是,进入了恶梦模式超时一个窗口就减半一下,多个超 时会超成TCP的传翰速度呈级数下降,而且也不会触发 Fast Recovery算法了 通常来说,正如我们前面所说的,SACK或 D-SACK的方法可以让 Fast Recovery或 Sende在做决定时更聪明一些,但是并不是所有的TCP的实现都支持 SACK(SACK需要两端都支持),所以,需要一个没有SACK的解决方炙。而通过SACK进行拥塞控制的算法是FACK(后面会讲) TCP New reno 于是,1995年, TCP New Reno(参见RFC6582)算法提出来,主要就是在没有SACK的支持下改进 Fast Recovery算法的 当dei到了3个 Duplicated Acks,进入 Fast Retransimi楨式,开发重传重复Aκ指示的那个包如果只有这一个包丢了,那么,重传这个包后回来的Ak会把整个已经被 sender传 输出去的数据xk回寀如有的話话,说明有多个包丢了。我山峧个ACK为 Partial ACK 旦sede这边发现了 Partial acK出现,驱么,se就可推理来有多个包被了,于是乎迷麵传 sliding window里末被ak的第一个包,直再也收不到了 Partial ack,才真正结束 Fast Recover这个过程 我们可以看到,这个“" Fast Recovery的变更”是一个非常激进的玩法,他同时延长了 Fast Retransmit和 Fast Recovery的过程 算法示意图 下面我们来看一个简单的图示以同时看一下上面的各种算法的样子 cwnd Duplicated Acks Duplicated Acks Duplicated Acks RT thresh low congestion congestion congestion sIcw congestion start avoIdance avoldance avoidance start avoidance FACK算法 FACK全称 Forward Acknowledgment算法,论文地址在这里(PDF) Forward Acknowledgement: Refining TCP Congestion Control.这个算法是其于 SACK的,前面我们说过SACK是使用了TCP扩展字段Ack了有哪些数据收到,哪些数据没有收到,他比 Fast retransmit的3个 duplicated acks好处在于,前者只 知道有包丢了,不知道是一个还是多个,而SACK可以准确的知道有哪些包丢了。所以,SACK可以让发送端这边在重传过程中,把那些丢掉的包重传,而不是 个一个的传,但这样的一来,如果重传的包数据比较多的话,又会导致本来就忙的网络就更忙了。所以,FACK用来做重传过程中的拥流控 这个算法去会把 大的 equence Number保存在 snd. fack这个变量中, snd fack的更新由ack带秋,如果网络切安好则和ndna样( sauna就是还有收到k的,t 是莉前面 sliding window厘的 category#2的第个地方) 后定义一个awnd=sndn- snd fack( sndt指端 iding window中在要被发的地—前面 sliding window图的aegy#3第个位置),这样aMn的意思 就是在络上的数据。(所胃amd意为: actual quantity of data outstanding in the network) 果需要重传魏据,那么,aWnd=snd.nxt-snd.fack+ retran data,也就是说,aMnd是,出去的+重传的数。 然 ast Recovery的条件是:(( snd. fack- snd una)>(3*MsS)川( dupacks==3)。这样来,就不需要等到3个 plicated acks才重传,而是只要sac中的最大的一 拗括和k的比长了(3个MSS),琼发重传。在整个重传过程中wd不变直第次丢包的 osnd nxt<= sauna(也是重的崴者獭认了),然后进来拥瘧避免初制 cWd线性上 我们可以看到如果没有FACK在,那么在丢包比较多的情况下,原来保守的算法会低估了需要使用的 window的大小,而需要几个RTT的时间才会完成恢复,而 FACK会比较激进地来干这事。但是,FACK如果在一个网终包会被 reordering的网络里会有很大的问题 其它拥空訓斧法筒介 TCP 拥害控制算法 这个算法1994年被提岀,它主要对 TCP Reno做了些修改。这个算法通过对RTT的非常重的监控来计算一个基准RTT。然后通过这个基准RTT来估计当前的网络实 际带宽,如果实际带宽比我们的期望的带宽要小或是要多的活,那么就开始线性圯减少或增加∝wn的大小。如果这个计算岀来的R∏大于了 Timeout后,那么 不等ack超时就直接重传。( Vegas的核心思想是用R的值来影响拥塞窗口,而不是通过丢包)这个算法的论文是《 ICP Vegas: End to end congestion Avoidance on a global internet》这篇论文给了Vega和 New reno的对比 TCP New Reno throughput with simulated background traffic +十 TCP Vegas throughput with simulated background traffic 关于这个算法实现,你可以参看 Linux源码:net/ipw4/ tcp vegas. h, net/ipv4/ tcp vegas.c HSTCP( High Speed TCP)算法 这个算法来自RFC3649( Wikipedia词条)。其对最基础的算法进行了更改,他使得 Congestion Window涨得快,减得慢。其中 用时的鹵口增长方式:cwd=cwnd+α(cwn/cwd 云包后下降方式:cMnd-(1-β(cwnd)cwnd 注:a(cwnd)和β(cwnd都是函数,如果你要让他们和标准的TCP一样,那么让a(cWnd=1,β(cwnd=0.5就可以了。对于 a(cwnd和阝(cwnd)的值是个动态的变 换的东西。关于这个算法的实现,你可以参看 Linux源码:/net/ip4/ tcp highspeed. c TCP BIC算法 2004年,产内出BIC算法。现在你还可以查得到相关的新间《 Google:美科学家研发BIC-TCP协议速度是DSL六千倍》BC全称 Binary Increase Congestion control,在 ELinux2.6.8中是默认拥塞控制算法。BC的发明者发这么多的拥塞控制算法都在努力找一个合适的cwnd- Congestion Window,而且 BIC-TCP的提 出者们看穿了事情的本质,其实这就是一个搜索的过程,所以BC这个算法主要用的是 Binary Search-一二分查找来干这个事。关于这个算法实现,你可以参看 Linux源码:net/ipwa/ tcp bic.c TCP Westwood算法 westwood采用和Reno相同的慢启动算法、拥塞避免算法。 westwood的主要改进方面:在发送端做带宽估计,当探测到天包时,根据带宽值来设置拥塞窗 口、慢启动阈值。那么,这个算法是怎么测量带宽的?每个R∏时间,会测量一次带宽,测量带宽的公式很简单,就是这段RT內成功被ak了多少字节。因为 这个带宽和用RTT计算RTO一样,也是需要从每个样本来平滑到一个值的——也是用一个加权移平均的公式。另外,我们知道,如果一个网络的带宽是每秒可以 发送X个字节,而RT是一个数据发出去后确认需要的时候,所以,X*RTT应该是我们缓冲区大小。所以,在这个算法中, ssthresh的值就是 est bD+min RTT(最小的RTT值),如果丢包是 Duplicated ACKs引起的,那么如果cwnd> ssthresh,则cwin= ssthresh。如果是RTO引起的,cwnd=1,进入慢启动 关于这个算法实现,你可以参看 Linux源码: net/ipv4/ tcp westwood.c 更多的算法,你可以从 Wikipedia的 TCP Congestion Avoidance Algorithm词条中找到相关的线索 后记 好了,到这里我想可以结末了,TCP发展到今天,里面的东西可以写上好几本书。本文主要目的,还是把你带入这些古典的基础技术和知识中,希望本文能让你 了解TCP,更希望本文能让你开始有学习这些基础或底层知识的兴趣和信心。 当然,TCP西太多了,不同的人可能有不同的理解,而且本文可能也会有一些荒谬之言甚至错误,还希望得到您的反馈和批评。 posted on201405-292046 Richard阅读(1099)评0)貓收藏引用所需分类网络

...展开详情
2015-08-06 上传 大小:1.09MB
举报 收藏
分享
UML那些事儿

内容简介   本书通过引用UML规格书里的图例和定义详细介绍了UML的特色和发展历史,六类UML图,元模型的说明,并且以StarUML为示范,讲解UML,工具如何落实UML概念,还介绍了活动图、控制节点、交互图、生命线、用例图等内容。   本书可作为高等院校计算机专业的教材和参考书,也可作为各类希望了解UML的人员的参考书。 目录 前言 第1章 UML概述 1.1 语言与方法 1.2 图形语言 1.3 国际标准 1.4 面向对象 第2章 六类UML图 2.1 类图 2.1.1 类 2.1.2 可见性 2.1.3 关联 2.1.4 多重性 2.1.5 聚合与组合 2.1.6 泛化

立即下载
UML那些事儿.pdf

UML那些事儿.pdf

立即下载
[UML那些事儿].邱郁惠.扫描版.pdf

[UML那些事儿].邱郁惠.扫描版.pdf,有编辑好的目录结构,希望能给想学习UML语言的小伙伴们带来帮助。。。。

立即下载
html+css+js制作的一个动态的新年贺卡

该代码是http://blog.csdn.net/qq_29656961/article/details/78155792博客里面的代码,代码里面有要用到的图片资源和音乐资源。

立即下载
qBittorrent插件集合(22个)

btetree.py cpasbien.py divxtotal.py ilcorsaronero.py kickass.py leetx.py limetorrents.py linuxtracker.py nyaa.py nyaapantsu.py nyaasi.py pantsu.py psychocydd.py rarbg.py rutor.py skytorrents.py sukebei.py sumotorrent.py tntvillage.py torrent9.py torrentfunk.py zooqle.py

立即下载
万能BIOS刷新工具Universal Flash Utility V8.95

近期在网搜刷新工具时,寻得这组万能刷新工具类型的希缺资源[正宗正版工具软件],特上传bios之家论坛,对号最需要它的爱好者群!软件版权归属原作品发布方,提供与本网站各界爱好者试用,以便交流刷新比较困难的 bios 实际使用经验![[ 其中的895工具是在本论坛首次亮像,=本论坛335469299用户曾在2011年6月29日发表过848的使用资料=各位可划文搜链接[ ==http://bbs.bios.net.cn/?8024== ]看 用户 awb 空间 所存载主题=求万能bios刷写工具flash849.exe-=之=-335469299 -=所回帖发布软件介绍使用参数 参考试用万能 bio

立即下载
基于eclipse+MySQL的图书馆管理系统

基于eclipse+MySQL的图书馆管理系统,可以实现读者的注册、借书和还书,管理员的管理等等操作,是一个功能全面的图书馆管理系统

立即下载
压缩包爆破解密工具(7z、rar、zip)

压缩包内包含三个工具,分别可以用来爆破解密7z压缩包、rar压缩包和zip压缩包。

立即下载
服务器CPU天梯图_最全CPU天梯图

主要是服务器CPU天梯图_最全CPU天梯图,文字版,不是图片

立即下载
公司年会滚动抽奖系统

基于HTML5和JS的公司年会抽奖系统。 该抽奖功能描述: 1).随机所有号码并且不重复出现。 2).中过奖的人,不能再进行抽奖。(不会中了2等奖在去中1等奖) 3).可以自定义抽奖的号码(姓名或数字),需要手动添加至HTML5代码中。

立即下载
工资单分割,可以将excel、xls工资单按照一定规则分割成多个文件

工资单分割,可以将excel、xls工资单按照一定规则分割成多个文件; 可以将EXCEL表格做成工资表后转换成每人一个单独的表格

立即下载
企业IT架构转型之道:阿里巴巴中台战略思想与架构实战(完整版)

企业IT架构转型之道:阿里巴巴中台战略思想与架构实战(完整版)

立即下载
2018年数模美赛全部题目A~F题(包括英文版,中文版)

这是我2018年参加数模美赛时全部题目A~F题,包括英文版,中文翻译版题目,适合参加数模国赛和美赛的同学熟悉一下题目。

立即下载
C++Primer.Plus(第6版)中文带完整书签.pdf

C++Primer.Plus(第6版)中文带完整书签.pdfC++Primer.Plus(第6版)中文带完整书签.pdfC++Primer.Plus(第6版)中文带完整书签.pdfC++Primer.Plus(第6版)中文带完整书签.pdf

立即下载