网络编程之-UDP详解
🌈个人主页:努力学编程’
⛅个人推荐:
c语言从初阶到进阶
JavaEE详解
数据结构
⚡学好数据结构,刷题刻不容缓:点击一起刷题
🌙心灵鸡汤:总有人要赢,为什么不能是我呢
🏀🏀🏀UDP 协议
学习一个网络协议就是学习 数据格式 和 报文格式 .
UDP的数据格式:
对于UDP的报头来说,长度是固定的,一共是八个字节,这其中并没有分隔符,而是通过指定的数据长度进行数据的分割,后面是UDP的正文部分.
UDP的报文长度是: 报头长度+载荷长度.
其中UDP的数据的长度单位是字节,即UDP的报文长度:1024->整个UDP的长度就是1024字节.由于表示长度的最大空间是2个字节,所以数据的最大长度是65535大概是64KB,所以我们使用UDP传输数据量大的信心的时候,就会变得非常,麻烦!!!
同时大家需要注意,在网络通信中,最重要的有四个关键信息:
源IP 目的IP
源端口 目的端口
就相当于你要发快递,就需要发件人的电话,收件人的地址,发件人的地址,收件人的电话
这里举一个使用UDP的例子:
在搜狗浏览器早期的时候,我们使用它搜索一个关键信息(不孕不育)的时候,就会出现如下情况:
这个搜索的过程可以模拟为以下场景:
对于广告服务器和搜狗的入口服务器之间的网络通信使用的是UDP协议,因为UDP不用考虑稳定传输,所以数据量很少的时候使用起来是非常香的~随着信息的递增,逐渐一个数据包的长度都快超过64KB了,
此时使用UDP就要对数据发生截断,那么就有两种解决的方案:
- 将数据进行分段,每一段使用UDP进行传输,(这个方案不大可能行得通,因为对数据进行截断有非常大的风险,同时还要对数据进行正确的重组,成本很大)
- 干脆直接舍弃UDP,使用稳定TCP,这样不仅解决的数据量大的问题,而且TCP具有稳定传输的特性,也会使数据的安全性得到保证.
🏀🏀🏀校验和
在网络编程的时候,是非常容易出现错误的,信息在传播的时候,是以电信号,光信号,…传播的,但是电场和磁场本身就是相互影响的,有时会出现这种情况:“0->1 1->0”,我们称为"比特翻转"这点在地球上不明显,在太空中我们经常要考虑这个问题…
为了能够正确识别我们传播的信息是否是正确的,UDP引入了校验和,这里我们并不是将数据全部拷贝一份,而是记录一些关键的信息,而且如果发现数据是有问题的,我们也不会要求发送方重新发送数据,而是直接将数据丢弃掉.
就好比现在我非常饿,点了一份外卖,等到快递小哥送到以后,我立马打开外卖,发现我点的明明是"鱼香茄子" 送来的却是 “鱼香肉丝” 但是由于我非常饿,于是就直接干了~~
🏆🏆🏆检验和的基本原理
举个很简单的例子:
有一天俺妈让俺去买菜,在我去之前告诉我你去卖 "西红柿,鸡蛋,黄瓜,茄子 "接着补充道:“一共四个哦”
这里的一共四个,就类似于UDP中的校验和,它并不能准确的识别数据的正确与否,而是大概记录数据的特征,而且容易误判(比如我把"鸡蛋"买成了"鸭蛋")~
如果我们希望校验和可以更加严格的对比数据,就需要根据数据的内容,格式去设计校验和.
那么校验和到底是怎样计算的呢,原理如下:
在UDP中我们使用两个字节作为校验和,计算校验和的方式为CRC校验和
就是将数据报中的整个数据进行遍历,去除每个字节,加到一个 两个字节的变量中,数据量大的时候,可能会导致计算的校验和信息存储的变量溢出,不过没关系,我们并不关心数据是否溢出,而是观察数据在传输的过程中是否发生改变~~
接收方此时会将接收的信息按照相似的算法重新计算校验和,checksum2,如果此时有 checksum1==checksum2,那么就说明数据传输成功,否则则说明数据传输的时候发生了改变.
在日后我们工作的时候,其实我们计算校验和的方式,也有其他很多种比如:
MD5算法,这个算法本质上是字符串hash算法.感兴趣的话可以了解一下.
🏀🏀🏀UDP TCP特点总结
对于UDP来说具有以下特点:
- 无连接:直到对方的IP和端口号即可,不需要建立连接
- 不可靠:没有确认机制,没有重传机制,如果因为网络故障数据传输失败,UDP协议层也不会给应用层返回任何错误信息,
- 面向数据报:不能够灵活的控制读写数据的次数和数量.
对于TCP来说:
它有确认应答机制,并且两方建立连接,面向字节流可以灵活的读取数据,即有保证数据可靠传输的机制(确认应答和超时重传)还有提高效率的机制(滑动窗口和捎带应答)
但是我们在传输少量且不那么重要的数据的时候,我们仍然优先考虑UDP因为他的速度真的很快!!!
🏀🏀🏀TCP状态转换汇总
建立链接的意义:
- 投石问路,确认当前信息路径是否畅通
- 协商参数,通信双方共同确认一些通信必备参数的数值.
🏆🏆🏆UDP是否也存在粘包问题
对于TCP我们知道由于它是面向字节流的,将接收到的数据全部存放到缓冲区中,但是我们对于数据有很多种的读取方式,所以很难正确读取数据,(在上一篇文章中已经详细讲解.有兴趣可以去看看)
那么UDP是否也存在这样的问题呢,首先UDP是面向数据报的,这样数据本身就具有明确的边界,站在UDP应用层的角度中,我们上文也提到了,UDP要么传输完整的报文,要么直接丢弃,不会出现 “半个” 的情况.
🏀🏀🏀异常情况
• 进程终⽌: 进程终⽌会释放⽂件描述符, 仍然可以发送FIN. 和正常关闭没有什么区别.
• 机器重启: 和进程终⽌的情况相同.
• 机器掉电/⽹线断开: 接收端认为连接还在, ⼀旦接收端有写⼊操作, 接收端发现连接已经不在了, 就
会进⾏reset. 即使没有写⼊操作, TCP⾃⼰也内置了⼀个保活定时器, 会定期询问对⽅是否还在. 如果
对⽅不在, 也会把连接释放.
另外, 应⽤层的某些协议, 也有⼀些这样的检测机制. 例如HTTP⻓连接中, 也会定期检测对⽅的状态. 例
如QQ, 在QQ断线之后, 也会定期尝试重新连接.