Tcp:面向连接,可靠的,字节流服务
Udp:无连接,不可靠的,数据报服务
服务类型
字节流:【“流”是指流入到进程或从进程流出的字节序列】应用层发送的次数,与接收的次数没有关系,tcp模块会先将发送端的数据放入tcp发送缓冲区中,当tcp模块真正开始发送数据时,tcp缓冲区中的数据可能会被封装成一个或多个tcp报文段发出(发送方由内核根据当前的网络情况(滑动窗口,拥塞控制)和对方给出的窗口值进行封装tcp报文段);(如果应用进程传送到tcp缓存的数据块1太长,tcp就把它划分短一些再传送,如果应用进程一次只发来一个字节,tcp也可以等待积累足够多的字节后再打包成报文段发送出去)。
数据报:应用层发送的次数与接收端接收的此时湖完全对等,每执行一次写操作,tcp模块就将其封装成一个udp报文段并发送,接收端必须及时针对每一udp报文段执行读操作,否则就会丢弃,如果用户没有指定足够的缓冲区来存放udp数据,则udp数据会被截断
Tcp的可靠性
保证数据能到达对端=======》应答确认&&超时重传
保证接收端接收到的数据是有序的==========》每一个tcp报文段都有序号
保证数据不失真==========》16位冗余检验码(校验和)
有流量控制===========》滑动窗口,拥塞控制
Tcp的头部结构
应答确认:tcp的头部包含了32位的确认号,用作对另一方发来的tcp报文段的响应。其值是收到的tcp报文段的序号值加1。
超时重传:tcp模块为每一个tcp报文段都维护了一个重传定时器,该定时器在tcp报文段第一次被发送时就启动,如果超时时间内未收到接收方的应答,tcp模块将重传tcp报文段并重置重传定时器,如果在超时时间内收到了应答就撤销已设置的重传定时器。(定时器的时间设定要根据每个分组会经过哪些网络以及这些网络将产生多大的时延决定)。
有序性:tcp的头部包含了32位序号,表示一次tcp通讯中某一个传输方向上的每个字节的编号。编号为某一个随机值+该报文段所携带数据的第一个字节在整个字节流中的偏移。
16位校验和:由发送方填充,接收端对接收到的tcp报文段进行CRC算法以检验tcp报文段在传输过程中是否损坏
流量控制:
滑动窗口(以字节为单位)
tcp的头部结构中有一部分是16位窗口大小,指的是接收通告窗口,用来告诉对方本端的TCP缓冲区中还能容纳多少字节的数据,这样对方就就可以控制发送数据的速度。
滑动窗口是将发送数据分成了四部分:
【 已发送并收到确认的数据(不再发送窗口和发送缓冲区之内)、
已发送但未收到确认的数据(位于发送窗口之中)、
允许发送但尚未发送的数据
发送窗口外发送缓冲区内暂时不发送的数据; 】
由接收通告窗口决定发送端每次能发送的数据大小。没有收到确认的数据,都必须暂时保留在窗口内,以便在超时重传时使用。发送窗口的大小由前沿和后沿决定,后沿有两种情况,不动(没有收到新的确认)和前移(收到了新的确认),不可能后移,因为不能撤销掉已收到的确认;前沿:会不断前移也有可能不变,不动(没有收到新的确认,对方的接收窗口也没变,或者,收到了新的确认,但对方通知的窗口变小了)。
当p3和p2重合时就是零窗口,即接收窗口目前没有多余的存储空间。Tcp为每一个链接设置一个持续计时器(防止对方发送的零窗口通知在传送过程丢失而导致的死锁僵局),只要tcp连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到了,就发送一个探测报文段(仅携带一个字节的数据),而对方就在确认这个探测报文段时给出了新的窗口值,如果窗口仍然是0,那么收到这个报文段的一方就重新设置这个持续计时器,如果窗口不是0,那么死锁的僵局就打破了。
每次成功发送数据之后,发送窗口就会在发送缓冲区中按顺序移动,将新的数据包含到窗口中准备发送;
接收窗口在给发送方发送确认报文时都会将自己的接收窗口大小发送给发送方。
连着发送2,3,4三个数据帧,2丢失了,是不能移动窗口的,接收端会先将3,4缓存下来,当收到3,4时还是会给发送端发送1号数据帧的确认报文,这样就连着给发送端发了三个一样的确认报文段(快速重传),发送方就知道2号数据帧丢失了,会立马重传2号数据。
拥塞控制(包含慢启动,拥塞避免,快速重传,快速重传四种算法)
拥塞控制:当网络发生拥塞时,路由器就要丢弃分组,因此只要发送方没有按时收到应当到达的确认报文,就可以猜想网络可能出现了拥塞。
拥塞控制包含四部分内容:慢启动、拥塞避免、快速重传、快速恢复。
发送窗口(SWND):发送端往网络中写入的最大数据量
SMSS:tcp报文段的最大长度
拥塞窗口CWND:
慢启动:网络传输刚开始时,并不知道网络的实际情况,所以采取一种试探的方式控制数据的发送速率。慢启动阶段,第一次cwnd设置为一个最大报文段MSS的数值(也不能超过两个报文段)。数据的发送速率以指数方式(上一次的二倍)增长,即就是拥塞窗口(cwnd)的增长,每次都是收到确认报文段数量的2倍。可以看出慢启动并不慢,拥塞窗口增长的速度很快。所以,为其设置了一个慢启动门限,当达到门限时,就进入到拥塞避免阶段。
每次发送拥塞窗口大小的数据,并CWND以指数形式增长,直到达到拥塞窗口门限,进入拥塞避免阶段。
拥塞避免: 当拥塞窗口的大小采用慢启动方式增长到慢启动门限时,就进入拥塞避免阶段,拥塞避免阶段不再以指数形式增长拥塞窗口,而是每经过一个往返时间RTT就将发送方的拥塞窗口+1(增加一个MSS的大小), 使其增长速度减缓。按照线性方式增长。如果发生网络拥塞,比如丢包时,就将慢启动门限设为当前拥塞窗口的一半,然后将拥塞窗口设置为1,开始进入慢启动算法。(较低的起点,指数级增长)。 快速重传: 假设发送方发送的报文段分别为: M1,M2,M3,M4,M5,M6 , 当接收方收到M1和M2后,M3报文段丢失,接着收到的M4,M5,M6都不做处理,而是每接收到一个报文段就对M2重复确认,发送方接收到重复的三次确认报文段,就对其后的报文段进行重新发送,而不需要等待超时时间到达。当快速重传后,将慢启动门限设置为原来的一半,立即进入到快速恢复阶段。
快速恢复:将慢启动门限设置为原来的一半,然后将拥塞窗口设置为现在的慢启动门限值,不再执行慢启动算法,而是直接进入拥塞避免阶段。使发送窗口成线性方式增大。
--------------------【滑动窗口与拥塞控制的区别】-------------------
滑动窗口是流量控制,流量控制指点对点通信量的控制,是个端到端的问题(接收端控制发送端),流量控制所要做的就是抑制发送端发送数据的速率,以便接收端来得及接收。
拥塞控制是防止过多的数据注入网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受先有的网络负荷。拥塞控制是一个全局性的过程,涉及所有的主机,所有的路由器,以及与降低网络传输性能有关的所有的因素。
Tcp的面向连接:即三次握手和四次挥手,参考上一篇文章
应用上的区别:
Tcp:tcp是面向连接的协议,所以tcp的服务器更加复杂,负担更重,tcp要保证可靠性,所以传输效率低,要多传输更多的控制信息,对网络的负担重。
Udp:发送效率高,及时性好,传输速度快(不面向链接,没有多余的控制信息),节省流量,适用场景,eg:视屏传输(直播,实时性),广播,多播(不面向链接)
抖音上的小视频,两者都可以。