一、TCP的可靠传输如何保证?
在TCP连接中,数据流必须以正确的顺序传送给对方。TCP的可靠性是通过顺序编号和确认(ACK)实现的。TCP在开始传送一个段时,为准备重传而首先将该段插入到发送队列中,同时启动时钟。然后,如果收到了接收端对该段的ACK信息,就将该段从队列中删去。如果在时钟规定的时间内,ACK未返回,那么就从发送队列中再次送出这个段。TCP在协议中就对数据可靠传输做了保障,握手与断开都需要通讯双方确认,数据传输也需要双方确认成功,在协议中还规定了:分包、重组、重传等规则;而UDP主要是面向不可靠连接的,不能保证数据正确到达目的地。
二、TCP还提供了以下方式保证可靠传输
1.确认和重传:接收方收到报文就会确认,发送方发送一段时间后没有收到确认就重传。
TCP是怎么保证错误重传的?
1)接收方受到错误的分组,就直接丢弃,而不做任何操作;
2)发送方在规定的时间(比平均往返时延大一些)没有收到分组的确认分组,就会自动重传;
3)为了让对方知道哪个分组出现了问题,就为分组也编了序号。
2.数据校验
3.数据合理分片和排序
UDP:IP数据报大于1500字节,大于MTU。这个时候发送方IP层就需要分片(fragmentation)把数据报分成若干片,使每一片都小于MTU,而接受方IP层则需要进行数据报的重组。这样就会多做许多事情而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,接收方便无法重组数据报,将导致丢弃整个UDP数据报。
TCP会按MTU合理分片,接收方会缓存未按序到达的数据,重新排序后再交给应用层。
4.流量控制
利用滑动窗口实现流量控制,如果发送方把数据发送的过快,接收方可能会来不及接收,这就会造成数据的丢失。所谓流量控制就是让发送方降低发送速率,让接收方来得及接收。原理就是运用TCP报文段中的窗口大小字段来控制,发送方的发送窗口不可以大于接受方发回的窗口大小。
时机:目的主机缓冲区变小而不能接收源主机更多的数据时,就要流量控制。
改变接收窗口:可随时改变窗口大小。目的主机在确认时,还向源主机告知目的主机接收缓冲区的大小。
滑动窗口机制:TCP协议里窗口机制有2种,一种是固定的窗口大小、一种是滑动的窗口。这个窗口大小就是我们一次传输几个数据。
思想:允许发送方不必等确认到来就可以继续发送下面的分组,但规定一个上限。若多个分组的确认未到时,则暂停发送。
1)数据流的各字节被编上序号。
2)TCP的滑动窗口按字节操作而不是按报文段或分组操作。
3)TCP窗口大小为字节数。最大为65535字节。
4)通信双方都没有发送和接收缓冲区(相当于发送窗口和接收窗口)。默认大小各系统有差异,如4096、8192、16384等。发送缓冲区大小为默认窗口大小。
5)TCP连接两端各有两个窗口(发送窗口和接收窗口)。
这里我们可以看到假设窗口的大小是1,也就是每次只能发送一个数据,只有接受方对这个数据进行确认了以后才能发送第2个数据。我们可以看到发送方每发送一个数据接受方就要给发送方一个ACK对这个数据进行确认。只有接收到了这个确认数据以后发送方才能传输下个数据。
这样我们考虑一下如果说窗口过小,那么当传输比较大的数据时需要不停的对数据进行确认,这个时候就会造成很大的延迟。如果说窗口的大小定义的过大。我们假设发送方一次发送100个数据,但是接受方还是只能处理50个数据。这样每次都会只对这50个数据进行确认。发送方下一次还是发送100个数据,但是接受方还是只能处理50个数据。这样就避免了不必要的数据来拥塞我们的链路。所以我们就引入了滑动窗口机制,窗口的大小并不是固定的而是根据我们之间的链路的带宽的大小,这个时候链路是否拥塞。接受方是否能处理这么多数据了。
TCP滑动窗口协议,窗口过大或过小有什么影响?
滑动窗口的大小对网络性能有很大的影响。
如果滑动窗口过小,极端的情况就是停止等待协议,发一个报文等一个ACK,会造成通信效率下降。
如果滑动窗口过大,网络容易拥塞,容易造成接收端的缓存不够而溢出,容易产生丢包现象,则需要多次发送重复的数据,耗费了网络带宽。
Nagle算法
Nagle算法是为了避免网络中存在太多的小包(协议头比例非常大)造成拥塞。Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。
算法如下:若发送应用进程要发送的数据逐个字节地送到TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方接收对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段再发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时,用这样的方法可明显地减少所用的网络带宽。Nagle算法还规定,当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。
它的主要职责是数据的累积,实际上有三个门槛:
1)缓冲区中的字节数达到了一定量(超过阈值MSS)
2)等待了一定的时间(一般的Nagle算法都是等待200ms)
3)紧急数据发送。
糊涂窗口综合症
设想一种情况:TCP接受方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1字节(这样就使接收缓存空间仅腾出1字节),然后向发送方发送确认,并把窗口设置为1字节(但发送的数据报是40字节长)。接着,发送方又发来1字节的数据(请注意:发送方发送的IP数据报时41字节长)。接收方发回确认,仍然将窗口设置为1字节。这样进行下去,使网络的效率很低。
要解决这个问题,可以让接收方等待一段时间,或者接收方缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接受方就发出确认报文,并向发送方通知当前的窗口大小。此外,发送方也不要发送太小的报文段,而是把数据积累成足够大的报文段,或达到接收方缓存的空间的一半大小。
上述两种方法可配合使用。使得在发送方不发送很小的报文段的同时,接收方也不要在缓存刚刚有一点小的空间就急忙把这个很小的窗口大小信息通知给发送法方。
5.拥塞控制:当网络拥塞时,减少数据的发送。
1)原理:在某段时间,若对网络中的某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变化,这种情况叫做拥塞。
2)方法:因特网建议标准RFC2581定义了进行拥塞控制的四种算法,即慢开始(Slow-start)、拥塞避免(CongestionAvoidance)、快重传(Fast Restrangsmit)和快恢复(Fast Recovery)。
慢开始:一开始先将阻塞窗口的cwnd设置为一个最大报文值(目的是试探一下网络的拥塞情况)。每次收到一个对新报文段的确认后,把拥塞窗口增加至多一个MSS的数值。用这样的方法逐步增大发送方的拥塞窗口cwnd,可以使分组注入到网络的速率更加合理。
为了防止拥塞窗口cwnd增长过大引起网络阻塞,还需要设置一个慢开始门限ssthresh状态变量(如何设置ssthresh)。慢开始门限ssthresh的用法如下:
当cwnd < ssthresh时,使用上述的满开始算法。
当cwnd > ssthresh时,停止使用慢开始算法而改用拥塞避免算法。
当cwnd = ssthresh时,即可使用慢开始算法,也可使用拥塞避免算法。
拥塞避免:让拥塞窗口cwnd缓慢地增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢的多。无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够的时间把队列中积压的分组处理完毕。
3)拥塞:交换节点(如路由器)数据报负载国中的现象。ICMP源站抑制报文,是一种被动机制。
4)必要性:在TCP层,拥塞造成时延增加,这又会造成超时重传,控制不当会进一步加重拥塞。TCP采用了一种主动控制机制。
5)拥塞控制技术
a. 拥塞窗口 cwnd
每个连接都有一个拥塞窗口,该窗口大小以字节为单位,但是增加和减少以MSS为单位;
初始大小:1个MSS;临界值:64KB;
发送方维护一个拥塞窗口(cwnd),拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞。
拥塞窗口的原则:只要网络没有出现拥塞,拥塞窗口就在增大一些,一边把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减少一些,以减少注入到网络中的分组数。
b. 加速递减技术
指数级递减:出现超时重传时,将临界值设为当前拥塞窗口的1/2,拥塞窗口恢复为1个MSS大小;
指数退避:对保留在发送窗口中的报文段,将重传时限加倍;
c. 慢启动技术
指数递增:每次成功发送一个MSS长度的报文段(成功发送是收到对应的确认),则发送方拥塞窗口加倍;
线性递增:增长到临界值后,每次增加一个MSS;
发送窗口=min(接受方窗口通告,cwnd)
总结一下:
1、在传递数据之前,会有三次握手来建立连接。
2、应用数据被分割成TCP认为最适合发送的数据块(按字节编号,合理分片)。这和UDP完全不同,应用程序产生的数据报长度将保持不变。(将数据截断为合理的长度)
3、当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。(超时重发)
4、当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒。(对于收到的请求,给出确认响应)(之所以推迟,可能是对包做完整校验)
5、TCP将保持它首部和数据的校验和。这是一个端到端的校验和,目的是检测数据在传输过程中的任何变化。如果收到段的校验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。(校验出包有错,丢弃报文段,不给出响应,TCP发送数据端,超时时会重发数据)
6、既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。(对失序数据进行重新排序,然后才交给应用层)
7、既然IP数据报会发生重复,TCP连接的接收端必须丢弃重复的数据。(对于重复数据,能够丢弃重复数据)
8、TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能容纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。(TCP可以进行流量控制,防止较快主机致使较慢主机的缓冲区溢出),TCP使用的流量控制协议是可变大小的滑动窗口协议。
9、TCP还能提供拥塞控制。当网络阻塞时,减少数据的发送。