[JavaEE初阶] 传输层协议---UDP 相关笔记
UDP特性
- 无连接
- 不可靠传输(我只管把数据发出去啊,其他的我就不管了嗷,不知道啊,导员没说)
- 面向数据报
- 全双工
UDP的报文格式
1.UDP报文格式竖着看
2.UDP报文内容详解
问题一:传输层协议和IP协议的区别:
- 传输层协议只需要考虑到端口号这一层
- IP协议要考虑IP地址
问题二:端口号是操作系统自己分配的吗?
- 服务器的端口号是程序员指定的(提前定好,客户端才能访问到)
- 客户端的端口是系统自动分配的空闲端口(
- 因为如果提前指定了客户端的端口号,可能会和客户端上其他的程序端口号 冲突,
- 其次客户端于服务器断开连接后系统会自动回收客户端的端口号,可以提高端口号的利用率,
- 也避免了端口号由于客户端的数量不断增加而成为一个超级巨大的数)
问题三:为啥不把报头上四个部分的的长度扩展到4个字节之类的呢?
- 这不是技术问题,而是zhengzhi问题:
- UDP这样的协议已经被内置到各种操作系统中了,拓展长度这样的操作已经算是破坏了UDP原有的结构了->相当于协议发生了变化
- 比如UDP大佬们推进了Linux修改UDP的结构
- 假设Linux同意修改了,那Windows会同意吗?mac会同意吗?
- 一旦一方改了另一方不改,就会导致这两个设备无法用UDP通信
- 谁先改,就会导致无法访问 没改的设备->造成巨大损失
- 所以就导致了一个局面:谁先改谁吃亏,其他人还不一定改
那就不能有一个业界第一人发号施令吗?
- 没有什么业界第一人,谁服你[狗头]
问题四:这个长度和表示正文的长度的请求头 之间有什么关系:
- 这里UDP报文的长度=报头+正文(载荷)
- UDP的报头固定是8个字节
- 这个长度和HTTP中 的Content-Length没什么关系
UDP传输上限问题
那么如何传输一个大的数据呢?(UDP只能存放长度上限为65535bit,也就是64kb的内容)
UDP协议在网络中的作用
后来,广告越来越多了
单个广告也越来越复杂
逐渐接近64kb上限了
如果放任不管,一旦广告数据超出了上限,就会导致数据被截断
页面拿到的数据可能会出错
那有人说,可以压缩再解压呀!
虽然压缩可以缩小体积,但是架不住广告越来越多
当时有两个方案:
- 方案1.应用层代码做拆包处理(一个大的应用层广告数据包,拆成多个小包,用多个UDP数据报传输)
- 缺点:工作量大,要写大量的逻辑来实现此处分包组包功能,并且需要进行复杂的验证
- 方案2.使用TCP协议,没有数据包长度的限制
UDP的校验和
校验和是验证数据是否发生修改的手段
HTTPS的数字签名,是为了防止黑客篡改服务器公钥
UDP的校验和不是为了防人,和安全性无关,而是为了防止出现数据传输过程中出现"比特翻转"
- HTTP协议的报头是文本格式的
- UDP/TCP/IP协议的报头是二进制的
什么是比特翻转?
- 由于信号是由光信号,电信号,电磁波 传播的,很容易受到外界干扰(比如太阳光子)什么的,可能会使高低电平 / 高低频光信号 发生改变
- 1->0
- 0->1
UDP的解决方法:
- UDP的校验和使用了CRC方式进行校验(循环冗余校验)
- 把每个字节(除了放 校验和 的那两个字节外), 都当做整数 进行累加,溢出也没关系,继续加,最终得到的结果就是 CRC校验和
- 把CRC校验和放入 UDP报头放校验和的位置
- 把整个UDP数据报发送给对端
- 对端收到数据后,再次使用 同样的 CRC校验算法 计算一遍 校验和
- 如果数据出现错误了, 对端算的那个校验和 和第一个校验和就会不一样
UDP发现数据校验和不对:
- 只会丢弃,不会触发重传操作
- 如果希望重传,要么使用TCP,要么在应用层代码中自己实现重传操作
但是,这样验证还是会有点小问题:
- 理论上来说,两个原始数据相同,使用相同的 校验和算法 ,得到的校验和也是相同的[真命题]
- 但是校验和相同,原始数据也一定相同吗?[可能存在变数]
- 例如前一个字节出现比特翻转,刚好小了1
- 后一个字节也出现比特翻转,刚好大了1
- 最终加到一起,校验和不变呀!
在地面上,比特翻转的概率很小,恰好两个翻转抵消了影响->小之又小->可以忽略不计
但要是给卫星,火箭写程序,由于高能粒子流很多,更大概率会对网络传输产生影响,
不仅是网络传输,还会影响到内存/硬盘的存储
->使用ECC内存(自带校验机制 的内存)
欲知后事如何,且听下回分解~
END✿✿ヽ(°▽°)ノ✿