一、确认应答机制
在TCP中,当发送端的数据到达接收端的主机时,接收端的主机会返回一个已经收到该消息的通知,这个通知就是确认应答(ACK)每一个ACK报文中带有对应的确认序号,意思就是告诉发送端,我成功接受了你发的哪些数据,下一次你应该从哪里开始发
***:
TCP将每一个字节的数据都进行了编号,即为***。
- TCP是面向字节流的,它对每一个字节都进行了编号,比如发送端发送了一个1~1000字节的数据,接收端拿到数据以后,就会回复一个ack=1001的确认号,表明1001字节之前的数据我都收到了。
- 每个ACK都带有对应的确认***,意思是告诉发送者,我已经收到了哪些数据,下一次你从哪里开始发送
- TCP在发送数据时,并不是按顺序发送的,接收端接收到数据之后,按序号排序,如果中间某个数据报丢失了,之后的数据报还是会被接收,但是不会对发送端返回之后的确认,而是会重复发送对丢失出之前的数据确认,保证发送端会对丢失的数据段进行重发。
- TCP规定,若确认号=N,则表明,到序号N-1为止的所有数据都已经正确的收到
- 建立连接时,双方发送的SYN报文和ACK报文段都是不携带数据的,但是会消耗一个序号,这个序号通常是随机值
- TCP规定,首部中序号字段的值是本报文段发送数据的第一个字节的序号。
二、超时重传机制
主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B ,如果主机A在一个特定的时间间隔内没有收到B发来的确认应答,就会进行重发,即超时重传。
但若A未收到B发来的确认应答,也有可能是ACK丢失了,此时A再次发送数据给B主机,B就会收到很多重复的数据,TCP协议就要识别出这些重复的包,并且把重复的丢弃掉,这个时候我们就可以利用前面提到的***,很容易就能达到去重的效果
超时重传的过程:
1. 放置片段到重传队列中,启动计时器:TCP在发送包含数据的片段后,片段都会被复制一份并放在重传队列中,然后启动计时器。
2. 确认处理:如果在计时器超时之前收到确认信息,就把该片段从重传队列中移除
3. 超时重传:如果在计时器超时之前没有收到确认信息,则相应片段被重新发送给对方,即重传机制,但是TCP也不能保证重传报文的可靠性,所以该报文依然会处于重传队列中,并重新计时,如果还是超时,则重复这一动作,而且超时时间会设置的较之前长,但是TCP只会重传一定数量的次数,因此当超过这个次数时,TCP会检查故障并断开连接
4. 这个等待的时间被称为RTO,RTO也是根据RTT(传输往返时间)来确定的,也和当时网络的状态有关系,需要通过具体算法实现,不是确定值
- 如果超时时间设置的太长,会影响整体的重传效率
- 如果超时时间设置的太短,会频繁发送很多重复的包
5.去重:当主机B的确认报文丢失时,主机A没有收到相应的确认报文,就会重传,主机B会收到重复的报文,TCP会根据报文中的***来移除重复收到的报文。
三、流量控制
1.利用滑动窗口实现流量控制
滑动窗口:
- 窗口大小是指无需等待确认应答而可以继续发送数据的最大值
- 在发送数据时并不是一次发送窗口的大小,而是将其分段,当第一段的数据收到一个ACK应答时,窗口就会向后滑动,继续发送下一段数据
- 操作系统内核为了维护滑动窗口,开辟了一个发送缓冲区,用来记录当前还有哪些数据没有应,只要没有应答过的数据,都要在缓冲区内保存,只有确认应答过的数据才能删除
流量控制过程:
接收端处理数据的速度是有限的,如果发送端发的太快,就会导致接收端的接收缓冲区被塞满,这时发送端再持续发送数据的话就会引起丢包,继而引发发送端的超时重传等等一系列反应,导致资源浪费。
TCP中引入了流量控制机制,意思就是根据接收端处理数据的能力来控制发送端发送数据的速度。
- 接收端将自己可以接收的缓冲区大小填充到TCP的报文头部中的“窗口大小”的字段中,通过ACK确认应答发送给发送端。
- 窗口大小字段越大,说明网络吞吐量。
- 如果接收端一旦发现自己的接收缓冲区快满了,就会将窗口大小设置为一个更小的值发送给发送端,发送端接收到这个窗口后,就会减缓自己的发送速度。
- 如果接收端接收缓冲区彻底满了,接收端就会将窗口大小设置为0,这时发送端便停止发送数据段,但是会定时的发送一个窗口探测报文,以此来获取接收端的接收缓冲区状态。
我们的TCP首部中有个16位窗口字段,但是实际的窗口大小最大值不一定是65535字节,TCP首部40字节选项中还有一个窗口扩大因子M,实际的窗口大小是窗口字段的值左移M位
四、拥塞控制
拥塞:既对资源的需求超过了可用的资源,若网络中许多资源同时供应不足,那么网络的性能就要明显的变坏,整个网络的吞吐量随之负荷的增大而下降。
拥塞控制:防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载. 拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷. 拥塞控制是一个全局性的过程,涉及到所有的主机,路由器,以及与降低网络传输性能有关的所有因素。
几种常见的控制方法: 慢开始,拥塞避免,快重传 , 快恢复。
慢开始和拥塞避免:
虽然TCP中有了滑动窗口机制,能够高效可靠的发送大量的数据,但是也不可以从一开始就发送大量数据段,因为网络上有很多的计算机,可能此时的网络就已经比较拥堵了,在不清楚当前网络的状态下,贸然发送大量数据,这就会严重影响TCP传输的效率和性能
TCP引入“慢启动”机制,开始先发送少量数据,探探路,当探清当前网络状态,再决定按照多大的速度发送数据
- 此处引入拥塞窗口的概念,TCP开始传输数据的时候,拥塞窗口设置为1
- 当收到一个ACK后,拥塞窗口加1,当经过一个传输轮次(其实就是往返时间RTT
)后,拥塞窗口就是加倍 每次发送数据段的时候,拿着拥塞窗口和接收端反馈的窗口大小作比较,取较小的值作为实际发送数据的大小拥塞窗口的增长是指数级别的,“慢启动”只是开始时比较慢,但是增长速度非常快-
但是拥塞窗口也有一个阈值,到达或超过阈值后就变为线性增长,而不是指数级别增长了。(也就是拥塞避免算法) -
当TCP开始启动的时候,慢启动阈值等于窗口最大值
-
每次超时重发时,慢启动的阈值就会编程原来的一半,同时拥塞窗口变成1
少量丢包,我们仅仅触发超时重传,如果丢大量的包,我们就认为网络拥塞
拥塞控制归根结底是,TCP协议想尽快的把数据传输给对方,但是又要避免给网络造成太大的压力的折中方法
快重传和快恢复:
快重传:
- 当1001~2000这段报文段丢失后,发送端就会以指收到1001的ACK,它告诉发送端,我收到了1~1000的数据报,我想要1001,但是后面的报文段它也会接收,却仍然发送丢失之前的应答
- 直到接收方连续三次收到同样一个“1001”这样的应答,就会将对应的数据“1001~2000”重新发送
- 接收端收到1001~2000之后,就会直接返回ACK=7000(因为2001~7000接收端之前都收到过了,都放在了接收缓冲区中),这就是快重传
与快重传配合使用的还有快恢复算法,其过程有以下两点:
- 当发送端连续收到三个重复确认,就执行“乘法减小”算法,把慢开始门限ssthresh减半,为了防止网络发送拥堵
- 由于发送端现在认为网络很有可能没有发生拥堵,因此与慢开始不同之处是现在不执行慢开始算法,而是将cwnd的值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大!