TCP 协议
TCP 协议是传输层最重要和最常用的协议。他提供一种面向连接的、可靠的数据传输服务,保证了端到端数据传输的可靠性。
1.面向连接:它向应用程序提供面向连接的服务,即两个通过TCP进行数据传输的时候、首先要进行TCP连接,并且在传输完成之后要释放连接。 2.全双工:TCP提供了全双工的服务、只要两个进程之间进行了TCP连接的话、那么两个进程之间就能双向的传输数据了,这种数据传输只是端到端之间的传输。 3.可靠:TCP协议提供流量控制的服务、解决接收方不能及时处理的数据;提供拥塞控制服务、解决因网络通信拥堵延迟带来的数据丢失问题;提供差错控制服务、解决了数据被破坏、重复、失序、丢失的问题。因此TCP协议是可靠的。 4.基于字节流:TCP提供了面向字节流服务,即TCP的传输是面向字节的,两个建立TCP连接的进程之间的通信交换的是字节流。当然、面向字节流的传输会带来粘包、半包的问题。
确认应答
在TCP中,当发送端的数据到达主机时,接收端的主机会返回一个已收到的消息的通知.这个消息就叫确认应答(ACK)TCP通过肯定的确认应答实现可靠的数据传输.
如果在一定的时间之内没有等到确认应答,那么发送端就可以认为数据已经丢失了,并进行重新发送.即是产生了丢包的问题,任然能够保证数据到达对面.
但是如果未收到确认应答不一定是接受端没有接收到消息,也可能是在确认应答在返回的途中丢失了,这就会导致重复发送的问题.TCP引入了序列号的机制—这种机制能够识别是否已经接受了数据,又能够判断是否需要接受.
序列号
序列号是按照顺序给发送数据的每一个字节都标上编号.接收端查询接收数据TCP首部的序列号和数据的长度,将自己下一步应该接受的序号作为确认应答返送回去.通过序列号和确认应答号,TCP就可以实现可靠的传输.
重发超时
超时重发指的是在重新发送数据之前,等待确认应答到达的那个特定的事件间隔。 如果超过了这个时间、发送端任然没有收到确认应答的话、那么就会重新发送这个数据。 数据在被重发之后、如果还是收不到确认应答的话、那么进行再次的发送、不过发送的时间间隔会以2倍、4倍的指数函数增长。 此外、数据不会被无限的、重复的发送。当到达一定的发送的次数之后、发送端任然没有收到确认应答的话、就会判断为网络或者对端主机发生了异常、强制关闭连接、并通知应用通信异常、并强行终止。
连接管理
UDP是一种无连接的通信协议、不检查对端是否可以通信,直接把UDP包发送过去。TCP恰好相反、他会在数据通信之前,通过TCP首部发送一个SYN包作为建立连接的请求并等待确认应答。如果对端的发送过来确认应答的话、那么则认为可以进行数据通信。也称TCP建立连接的过程为 “三次握手”
TCP连接断开的过程也称为 “四次挥手”:发送端发送 FIN 给对端 , 对端发送针对FIN的ACK给发送端、对端发送FIN给发送端、发送端发送ACK给对端。
段:TCP以段为单位发送数据,在TCP建立连接的同时、也可以确定发送数据包的单位、称其为:MSS (Maximum Segment Size)。最理想的情况就是MSS的长度正好是IP中不会被分片处理的最大数据长度。TCP在传输大量的数据的时候、是以MSS大小的数据进行数据分割发送的。重发的时候也是以MSS为单位。 MSS 是在三次握手的时候确定的。两端的主机在建立连接的时候、会在TCP的首部写入MSS选项、告诉对方自己能够适应的MSS的大小、然后会在两者之间选择一个最小的值使用。
窗口
如果收到2001的ACK 的话、那么2001之前的数据就没有必要进行重发。就会变成下面的样子👇
窗口大小:窗口的大小就是指的是无需等待确认应答就可以继续发送的数据的最大值。
滑动窗口
首先TCP发送数据的时候以一个段为单位,每发一个段就进行一次确认应答的处理。这样的传输方式有一个缺点。那就是,包的往返事件越长、通信的效率就越低。
为了解决这个问题,TCP引入了窗口的概念。如下图所示:确认应答不再是以每个段,而是以更大的单位进行确认的。也就是发送端在发送了一个段之后、不需要一直等待确认应答,而是继续发送。下图中滑动窗口的大小为3个段。
在窗口中的数据即使没有收到确认应答也可以继续发送出去。那么如果在途中出现了数据丢失的话、这种情况也需要重发。缓冲区就起到了作用:发送端在等到确认应答返回之前必需要在缓冲区保留这部分的数据。
在滑动窗口以外的部分保留着尚未发送的数据和已经发送的数据但是尚未进行确认应答的数据。当数据发出之后如期的收到了ACK之后的话、那么这部分的数据就可以被缓冲区清除了。 在收到确认应答之后、将窗口滑动到确认应答中的序列号的位置,这样就可以顺序的将多个段同时的发送、这样就提高了通信的效率。
滑动窗口与重发控制
1.如果只是ACK在发送的时候丢失了、那么有了滑动窗口的话、是不会进行重发的。因为可以在下次ACK的时候确认上次的ACK。
2.但是如果是发送端的数据包丢失了的话、那么在连续收到3次同一个ACK的时候、就会对对应的数据进行重发。这种机制比之前的超时重发的机制更加的高效、所以也被称为高速重发机制。
流控制
流控制: 发送端根据自己的实际情况发送数据、但是接收端收到的可能是一个毫无关系的数据包、会对这个毫无关系的数据包做一系列的其他的处理、会消耗时间,由如果接收端将这种数据包丢弃的话、那么就会触发重发机制、又导致网络流量的浪费。 为了防止这种现象的诞生、TCP提供了这个机制:就是让发送端根据接收端的实际的接受能力控制发送的数据量。这就是流控制、也叫流量控制。具体的操作就是:接收端向发送端通知自己可以接受的数据的大小、于是发送端会发送不超过这个限度的数据。该大小限度就被称为窗口大小。在TCP的首部专门有一个字段用来通知窗口的大小。接受主机将自己可以接收的缓冲区的大小放入到这个字段当中去通知给发送端。 接收端的这个缓冲区一旦面临数据溢出的问题的话、那么窗口的值也会随之被设置为一个更小的值通知给发送端、从而控制数据的发送量。 也就是发送端主机会根据接收端主机的通知,对发送的数据量进行控制。这就是一个完整的TCP流控制。 当接收端的缓冲区满的时候、就会停止接受数据、在收到窗口更新的通知之后才会继续发送、如果窗口的更新通知在途中丢失的情况下、可能就会导致通信无法进行。也就有了上面的机制:发送端会时不时的发送一个叫做窗口探测的数据段、此数据段只含有一个字节、来获取窗口的大小信息。
拥塞控制
有了滑动窗口、收发主机之间不在以一个数据段为单位发送确认应答,也能够发送大量的数据包。然而、在通信刚开始的时候就发送大量的数据,也可能会引发其它的问题。 TCP为了防止该问题的出现、在通信一开始的时候就会通过一个叫慢启动的算法得出的数值、对发送数据量进行控制。 首先为了在发送端调节要发送的数据的量、定义了一个叫做“拥塞窗口”的概念。 在慢启动的时候、将拥塞窗口的大小设置为1MSS,之后每收到一次ACK的时候、拥塞窗口的的值就+1. 不过、随着包的每次的往返、拥塞窗口会以1、2、4指数的方式进行增长,可能会导致网络拥堵的发生。为了防止这些的发生、就引入了慢启动阈值的概念。只要拥塞窗口的值超过这个阈值的话、那么在每次收到确认应答的时候、就会以下面的比列放大拥塞窗口:
延迟确认应答
TCP中为了提高网络的利用率使用了一个叫做 Nagle的算法。该算法指的是发送端即使还有要发送的数据的话、如果这部分的数据很少的话、则进行延迟发送的一种处理机制。 延迟确认应答: 如果接受数据的主机每次都立刻恢复确认应答的话、可能会返回一个较小的窗口、那是因为刚接收完数据、缓冲区已经满了。 当某个接收端接收到这个窗口之后、会以它为上限发送数据,从而又降低了网络的利用率。为此、引入了一个方法、就是接收到数据之后、不立即的进行返回确认应答、而是延迟一段时间的机制。
那么延迟多长的时间呢?在没有收到2MSS的时候不进行确认应答。 其它的情况下,最多延迟0.5秒,很多的操作系统设置的都是0.2秒 TCP在传输文件的过程中,大多都是采用每两个数据段返回一次确认应答:
捎带应答
就是字面的意思。在TCP的ACK和回执数据可以通过一个数据包发送、这就叫做捎带应答、可以是发送或者接受的数据量减少。 就是指的是在同一个TCP的包中即发送数据又发送确认应答的一种机制、由此计算机的负荷会减轻、网络的利用率也会提高。不过捎带应答必需要等待应用处理完数据并将作为回执的数据返回之后,才能进行捎带应答。也就是如果没有延迟应答的话、那么捎带应答就无法实现。因为如果刚接收到数据包就发送确认应答的话、那么应用还没有处理完数据就返回了、就不会有捎带应答了。
|