TCP 笔记
TCP概述
- TCP是面向连接的传输层协议,意思就是在TCP开始工作也就是开始传输的时候,必须先建立连接。
- TCP是端到端,点到点的连接。也就是发送方和接收方必须是一个点,也就是一对一,不能广播,也不能多播。
- TCP是可靠的服务,要在不可靠的链路上提供可靠的传输。
- TCP提供的是全双工通信,意思是双方都可以同时收发,潜台词是有接收缓冲池和发送缓冲池。
- TCP是面向字节流,注意这里是字节流,而不是比特流,也就是TCP的一切单位都是基于字节的。
TCP 可靠传输
可靠传输的意义或者目的就是在不可靠的链路上提供可靠的传输。
在谢希仁《计算机网络》书中,讲述可靠传输的思路是:
-
先简述了停止等待协议(ARQ),其思想精髓是引入了确认机制和超时重传机制。确认机制保证了发送方知道发送报文已经到达了接收方,但是此时接收方并不知道确认报文是否到达了发送方,所以有必要引入报文编号的概念,即发送方此时发送一个刚接收到的确认报文中的确认号加一的一个数据报文,此时该数据报文有两重意义:1)可以传送接下来的数据 2)可以通知发送发我已经接收到了你发送给我的之前的确认报文。如果网络发生了超时或者接收方接收到的报文检验出错,当然此时发送发什么也不知道,只是知道自己的计时器发生超过了计时门限还没有收到确认报文,所以就重新发送之前的报文。
-
因为停止等待协议(ARQ)的网络利用率比较低,所以引入了发送窗口和累计确认的概念。累计确认的概念是在有了发送窗口的概念之后才出现的,其目的是也是为了减少网络的拥塞程度,减少不必要的网络流量的浪费。之前的停止等待协议(ARQ)是单个报文单个报文发送的,为了发送下一个报文必须要等待上一个报文的确认报文的到达。然而这样的情况一般都是可以实现的,也就是讲网络状态一般是良好的,所以我们可以在等待先前报文的确认报文到达之前的这段时间内连续发送一些报文,但是这些报文的数目要有限制,(这个限制就叫做发送窗口),一方面是考虑到计算机网络的状态可能会随着连续发送报文而可能导致拥塞,另一个方面考虑到接收方接收缓存的物理大小限制。假设现在接收方接收到了许多连续的报文(之所以能判断连续是因为事先编号了,这个在ARQ就存在),但是这些连续报文的确认报文不需要逐个序号发送确认,只需要发送连续报文的最后一个报文的确认报文。这就是累计确认,意思是累积到接收到不连续的报文才发送确认报文。
-
TCP可靠传输的具体实现是基于发送窗口的,发送窗口上有三个指针$p_1,p_2,p_3 $ , $p_1$ 指向滑动窗口的起始位置,$p_2$指向已经发送但是没有接收到确认报文的位置,$p_3$指向发送窗口的最后位置。
认为可靠传输的最主要的思想或者精髓就是确认机制和连续发送机制,确认机制使得发送方知道我接收到了发送报文,连续发送机制前提是编号,连续发送让接收方知道了确认报文已经到达了发送方。但是如果设置了发送窗口,这种能确认报文已经到达了发送方的功能就消失了,因为无论发送方是否接收到了确认报文,都会连续发送窗口内的报文。
TCP 流量控制
流量控制是一个端到端的过程,主要实现手段是借助接收方通过控制发送方的发送窗口,从而实现控制发送方一次性能连续发送的报文数目。因为可靠传输时,发送方在一遍传输数据报文,一边同时接受接收方发来的确认报文,在确认报文中有接收方依据自身情况而定的给发送方的发送窗口值,发送方依据确认报文的窗口值调整$p_3$指针,也就是发送窗口的前沿,如果前沿向后缩小,说明接收方此时的接收能力很弱;如果前沿向前扩展,说明界树坊此时的接受能力很强。就这样接收方通过将自己的接受能力写进确认报文通知发送方,这样就可以使得发送方依据接收方此时的接受能力调整自己的发送窗口,实现流量控制。
考虑传输效率问题
应用层的程序将数据发送到TCP缓存中的时候,接下来发送任务就交由TCP来控制了,在窗口值满足的情况下,比如可以在满足最大报文段长度MSS的情况下发送数据,也可以在发送方的一个计时器到了,才发送,当然不能满足最大报文段长度MSS。但是无论如何,何时发送多少字节流,都是很难的问题。
Nagle算法是针对发送方的,为了提高网络的吞吐量(利用率),但又要不使得网络发生拥塞。算法如下:发送方先把缓存中的第一个自己发送出去,把后面到达的数据缓存在发送缓存中,如果接收到接收方的确认报文,则发送方把缓存数据都发送出去(当然有发送窗口的限制),然后对随后的应用层的数据再进行缓存,直到接收到上一次的确认报文,再一次性发送缓存中的数据。当然还规定,当缓存数据已经到发送窗口大小的一半或者达到最大报文段长度MSS时候,就立即发送一个报文段。
糊涂窗口综合症是针对接收方而言的,当接收方缓存已经满的时候,如果接收方应用层应用程序每处理一个字节数据,接收缓存就会空出一个位置,这时接收方有可能会发送一个确认报文,会附上给发送方的发送窗口是1的值,这样发送方就会发送一个携带一个数据的报文段,这样就会使得网络的利用率不是很高,所以要限制这种现象的发生。解决方法是,当接收方接收缓存空余极少空间时候,不要对发送方发送确认报文段,而是当接收缓存空闲空间到达一定阈值的时候才发送确认报文。
TCP拥塞控制
拥塞控制就是防止过多的流量同时注入网络当中,这是一个全局的概念,网络拥塞有可能发生在网络传输过程的一段或者是一个点,也可能是全部网络,在这些情况下发生了过载现象,例如某一个节点(路由器,交换机)过载,或者一段网络的带宽较低等等。网络出现了拥塞现象,猜想某处可能出现了拥塞,但是不知具体位置,也不知具体原因,所以拥塞控制很难解决。
流量控制是一个端到端的过程,它的主体是端点,例如客户端和FTP服务器,两台web服务器等等,具体做法是一端通过一些手段通知另一端尽可能的按照我能接收的流浪进行传输,防止出现本地过载现象。
拥塞控制之所以会和流量控制容易混淆,是因为拥塞控制的手段和流量控制的手段常常相似,拥塞控制虽然是全局出现了问题,但是手段经常也是向发送端发送控制,告诉网络出现了拥塞,发送端需要减少发送流量。这就和流量控制相似,也是通过发给发送端的一些信息,例如窗口大小,来控制发送端的发送流量大小。
拥塞控制可以分为开环控制和闭环控制,开环控制方法就是涉及网络时候,现将有可能发生拥塞控制的因素全不考虑周到,力求在整个网络中不产生拥塞,一旦整个系统运行起来,就不再中途改正。闭环控制是基于反馈环路的概念。闭环控制有以下几种措施:1)能够检测网络何时何地发生了拥塞;2)网络能够把发生的拥塞发送到能够处理拥塞的地方;3)能够调整整个网络解决拥塞。
TCP的拥塞控制的实现方法:1)慢开始 2)拥塞控制避免 3)快开始重传 4)快传输恢复
其中慢开始和拥塞避免是在一起使用,(如果使用了快重传和快恢复算法)使用情况只是只在网络超时,就是发送发在指定计数器到达时候没有接收到确认报文,认为网络发生了拥塞。
快重传是区别于慢开始和拥塞避免的新的动作,快重传的动作是指:接收方接收到无序报文的时候,给发送方发送最近一次接收到的有序报文的确认报文给发送方,发送方继续发送两个报文,如果接收方在接收到新发送的两个报文的情况下,还没有收到之前的无序报文中缺失的报文,就重发发送相同的确认报文给接收者,当接收者收到相同报文三次的时候,就开始快恢复状态。
两个概念:拥塞窗口(cwnd),拥塞门限(ssthrest)。
慢开始状态是指每次一个传输轮回正常时候,发送者就将下次发送的拥塞窗口(cwnd)指数增长一下,这样一直持续到拥塞窗口值到达设置的拥塞门限(ssthresh),此时开始拥塞避免(意思就是为了避免接下来的拥塞),拥塞避免将原来本来指数增长的拥塞窗口开始线性加一增长,一直到传输轮回不正常的阶段,就是没有发送方没有接收到确认报文,发送方认为网络出现了拥塞,此时重新开始慢开始动作,但是此时慢开始动作的拥塞门限(sshhresh)调整为原来的出现拥塞的时候拥塞窗口(cwnd)的一半。参考P219谢希仁《计算机网络》。
上面的直到拥塞真正出现了才开始减少拥塞窗口(cwnd)的值,而且直接减小到慢开始刚开始启动的初始值1,顺便调整拥塞门限(ssthrest)的值为拥塞窗口(cwnd)的一半,主要是重新开始一个慢开始动作很是费时,但是没有办法,因为这个时候网络已经出现了拥塞,最保险的办法就是重新初始化。那有没有一种方法能够在拥塞可能即将出现的时候检测到,这样就可以适当减小拥塞窗口,不用将其减小到初始值,这样就能增大网络的带宽利用率了。快重传的思想就是这样。
快重传是在当接收方接收到无序报文的时候就认为有可能要出现拥塞,并且接收方通过发送一个收到的最后一个连续报文的确认报文来告知发送发可能出现了拥塞,双方为了确认是否真正发生了拥塞,发送方通过连续发送两个即将要发送的报文,看在这两个报文传送到发送方的过程中,接收方有没有发过来之前无序报文的确认报文,如果没有,并且发送发接受到的是两个一样的先前缺失的无序报文的确认报文,(注意这时候发送方接收到了三个相同的确认报文,这就是快重传希望检测到的结果,也是快恢复要开始的标志)就认定当前网络已经要即将发生拥塞,此刻不可以认为网络已经发生了拥塞,因为新发送的两个报文可以顺利到达接收方,并且确认报文可以顺利的接收到,所以网络现在最多也是即将发生拥塞。快重传结束,并且发送方接收到了三个相同的确认报文,快恢复开始。首先将此时的拥塞窗口(cwnd)设置为原来的拥塞窗口(cwnd)的一半,而不是初始值,同样,慢启动的过程也被省略,直接开始拥塞避免阶段,即拥塞窗(cwnd)线性加一(当然,同样,拥塞门限(ssthrest)也减半)。