UDP/TCP协议知识及相关机制
一.UDP协议
UDP是一种无连接、不可靠、面向报文、全双工传输层的协议~
1.无连接 : 知道对端的端口号和IP可以直接传输,不需要建立连接
2..不可靠:没有确认机制,没有重传机制,不知道数据包能否能正确到达对端(丢包)!
3.面向数据报:应用层交给UDP多长的报文,UDP原样发生,既不发生拆分,也不发生合并!
4.全双工:通信双方既可以发送数据也可以接受数据~
UDP协议的格式
校验和:用于保证数据在传输过程中没有被破坏~,但是不能够确定这个数据100%正确~~
如果校验和验证失败,通常接收端会丢弃这个UDP数据包
UDP的报文是由8字节的报头和数据的大小~
这个16位UDP长度~~包含报头和数据~~
理论上这个UDP数据报最大的长度为2^16=65535的字节~~也就越等于64KB~~
那么UDP数据报能传输多少数据~
65535 - 20(IP协议的头部)- 8(UDP头部) = 65507字节
因为UDP协议时承载在IP包里的 !
看下图!👇
二.TCP协议
TCP是一种有连接、可靠、面向字节流、全双工的传输层的协议
可靠性:不是指的百分百可靠~~有几率会出错~
面向字节流:TCP协议将数据视为一个连续的字节流,不关心数据的边界。接收方只关注字节流的顺序和内容,而不关心数据是如何分割成不同的段发送的~~也就是说数据可以被分割成很多份来进行发送
TCP协议的格式
报头和载荷部分~~
这个TCP协议的格式中的相关内容,我们从讲解TCP协议中的相关机制来进行引入~~
序列号
序列号:序列号标识每个字节在数据流中的位置~~用来确保数据正确发送,不会出现错乱~
以发消息为例~假如你现在正在发送消息。
现在你要给对端发送消息~~.这个消息会以服务器为中介,进而把消息发送到对端~~
但是因为TCP是面向字节流的,而且传输路径也会有差异~所以数据到达对端的时间也会不同~
为了防止其出现错乱,所以引入了序列号,用来确保数据的正确位置~
确认应答
确认应答是用来确保数据可靠性一种机制
ACK:表示确认号是否有效:0表示无效,1表示有效。此时这里为1
由上述图可得~~
发送方给接收方发送了1~1000个数据,接收方给发送方返回了ACK,表示1~1000的数据我都接收到了,此时发送方就可以发送1001~2000的数据了~~依次持续!!
超时重传
超时重传确保数据可靠性的机制。顾名思义:如果某个数据发生了丢包这种情况,等待了一会,还是没有这个包,就会发生重传~~
为什么会发生丢包问题?
在实际的互联网环境中,链路可能拥塞,路由器可能丢包,物理线路也可能出现短暂故障,导致数据丢失~
1.发送方发生丢包问题~~
2.接收方返回ack时发生丢包问题~~
这张图,你是不是发现了一个问题~~主机B收到了两次1-1000的数据包~~这就有问题了~~
例如:这场景如果发生在扣款的过程中,如果已经了扣了一次款,但没有接收到应答~,就又扣了一次款~你的钱包就会默默得少了~~哈哈
看下图~~
注意:接收缓冲区不仅可以进行去重,也可以进行排序~~
那么超时重传的时间应该如何确定~~
如果超时时间设得太长~会影响整体得重传效率~~如果超时时间设置的太短,又可能会频繁发送重复的包~~所以我们需要确保重传的时间~~
TCP为了保证效能~~会动态地计算这个最大超时时间~~
在Linux中,超时以500ms为一个单位来进行控制~~,每次判定地超时时间都是500ms地整数倍~~如果重发一次之后,接收不到应答~~会等待2*500ms来进行重传~~此时,还没又接收到应答~·等待4*500ms进行重传~~依次类推~~如果仍然接收不到~~TCP会强制关闭连接~~
连接管理
1.三次握手(建立连接)
三此握手的意义
1.三次握手,可以针对通信路径,进行投石问路~~初步的确认一下通信链路是否
畅通~~
2.三次握手,也在验证通信双方,发送能力和接收能力是否正确~~
3.三次握手在过程中也会协商一些必要的参数~~例如:初始序列号、窗口大小、MSS(控制报文中的最大长度)
2.四次挥手(断开连接)
这次以客户端为例,服务器也可以进行断开连接~~
客户端给服务器发送fin表示数据发送完了,我想断开连接~
服务器接收到之后,给客户端返回ack
服务器给客户端发送fin ,表示我这帮也处理完了,可以断开连接~~
客户端给服务器返回ack,服务器接收到之后,成功断开连接~~
你们是不是有个问题~~中间的fin和ack能不能合并成一条~~直接发送给客户端
被动断开连接的中仍然需要一些时间继续发送未完成的数据~~
所以ack和fin中有时间间隔~~不能简单合并~~
如果说服务器挂了,也可以触发四次挥手~~
滑动窗口
滑动窗口是来优化TCP协议传输数据的效率~~如果像之前一样你每发送1字节的数据,都需要ack,依次往后推!这样效率就会太慢了~~所以引入了滑动窗口的机制~
滑动窗口~
是通过批量传输~~,现在先发一个数据,不等ack,再发下一个,继续往下发,连续发送了一定的数据之后统一等一波ack~~
如果出现了丢包情况~~应该怎么处理?
接收方出现丢包~~
发送方发生丢包~~
假如说1~1000的数据发生了丢包~~主机B给A返回的ack就一直是0,但同时主机B记录着后序的数据包的序号,只要主机A重传之后丢失的数据包~~,主机B便会返回ack就是主机A上一个序号+1
流量控制
接收端处理数据的速度是有限的,如果发送端数据发送的过快,导致接受端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包~继而会引起丢重传等一系列的连锁反应
所以引入流量控制的机制~~
接受端将自己可以接收的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK端通知发送端~~
窗口大小字段越大,说明网络的吞吐量越高~~
接收端一旦发现自己的缓冲区块满了,就会将窗口大小设置成一个更小的值通知给发送端~
发送端接收到这个窗口之后,就会减慢自己的发送速度~
如果接收缓冲区满了,就会将窗口设置为0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接受端把窗口大小告诉对端~~
拥塞控制
拥塞控制是指:防止网络中的数据太多,造成网络链路拥堵,从而导致整体通信性能下降的一套机制~~
1.TCP中引入慢启动机制,刚开始窗口的大小是0,先发少量的数据~~如果传输的数据,没有出现丢包~然后就要增大窗口大小~~增大方式是按照指数来增长~~
2.指数增长,不会一直持续保持的~~可能会增长太快~,一下子就导致
网络拥堵~~引入一个阈值之后,指数增长就变成了线性增长~
3.线性增长也是一直再增长,积累一段时间之后,传输的速度可能过快~~从而导致了丢包~~就会触发快速重传~~进行乘法减少~~这里假设设置直接减少为原来一般~~
4.然后进入恢复阶段,继续线性增长~~
我所说的就是如下图👇!!
延迟应答
如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小~~
所以要对ACK进行延迟,从而增大窗口大小,进而提升了数据传输的效率~~
如下图
下图就体现了延迟应答的机制~~
捎带应答
捎带应答:是指在发送方向接收方发送数据时,顺便把对接收方上一份数据的确认(ACK)信息一起带上发送,而不是单独发送确认~
假设A向B发送数据~~B收到后需要发送ACK确认~~如果B也正好要向A发送数据,那么它可以把ACK捎带在自己的数据包中一起发出去,这样就避免了单独发送ACK的额外开销~~
这样可以提升传输效率~~
粘包问题
在使用TCP协议来进行数据传输时,接收方一次性读取了多个发送方发送的数据包,导致多个消息粘连在一起,边界不清楚的现象
如何处理粘包问题~~
1.定长消息
每个消息固定长度,接收方按长度读取~~
2.特殊分隔符~
使用特定字符(\n,\0)来标识信息结束
3.消息头加长度字段~~
在每个消息前加上表示长度的字段~~
异常情况
(1).其中一方发生了进程崩溃~~
进程无论时正常就结束,还时异常崩溃,都会触发回收文件资源~也就会触发四次挥手~~
因为TCP连接的生命周期,比进程更长一些。虽然进程已经退出,但是TCP连接还在,仍然可以触发四次挥手~~
(2).其中有一方出现关机
当有个主机,触发关机操作,就会先强制终止所有的进程~~终止进程自然就会触发4次挥手~~
注意:如果挥的不快,至少也能把第一个fin发给对端~~对端接收带fin之后,就要向对方发送ack
但是因为对方关机了,就会触发超时重传的机制~当重传几次之后,自然会断开连接~~
(3).其中一方出现了断电~
如果说断电的是接收方~~发送方就会突然发现没有ack了,就要重传~
重传了几次之后还是不行~~
TCP就会尝试“复位(RST)”连接,相当于清楚原来的TCP中的各种临时书库~重新开始~此时的
RST网页不会有ack,重置了还不行,单方面放弃连接~
如果说断电的是发送方??接收方本来也就在阻塞等待?结果迟迟每来消息~
怎么办?这个情况下,接收方需要区分出,是发送方挂了,还是好着内但是没有发送消息~
如果接收方等待了一段时间之后,没有收到对方的消息,就会吃醋发“心跳包”来询问对方的情况~~如果多次心跳包没有响应,则认为对端挂了~~
总结:
如果有相关的问题,大佬可以指证下~~文章有错误,在所难免~~