JavaEE:网络编程(UDP)
文章目录
- UDP
- UDP的特点
- UDP协议端格式
- 校验和
- 前置知识
- 校验和具体是如何工作的?
UDP
UDP的特点
UDP传输的过程类似于寄信.
- 无连接: 知道对端的IP和端口号就直接进行传输,不需要建立连接.
- 不可靠: 没有确认机制,没有重传机制,如果因为网络故障导致该段无法到达对方,UDP协议也不会给应用层返回任何错误信息.
- 面向数据报: 不能够灵活的控制读写数据的次数和数量.
UDP协议端格式
学习一个网络协议,主要就是学习"数据格式",“报文格式”.
上图为了排版,于是进行了换行,实际上UDP的数据是一整行的,并没有换行操作~
UDP报头是固定长度的,总共8个字节.
报头中的四个字段,没有指定分隔符,而是通过固定长度来进行区分的.
可以看到我们是使用2个字节的长度来表示端口号的.如果端口号超过2个字节,那么这个端口号就会在系统底层被"截断".
- 源端口,目的端口: 在网络通信中,涉及到四个关键信息,源IP,目的IP,源端口,目的端口.
我们可以认为它们分别对应发件人地址,收件人地址,发件人电话,收件人电话.
- UDP报文长度:
UDP报文长度,就是报头长度+载荷长度.
报文长度的单位是"字节".
比如,报文长度为1024,这就表示整个UDP数据报就是1024字节.
由于是使用2个字节来表示这个长度,它的最大值就为65535,也就是64kb.
换句话说UDP能传输的数据最大长度就是64kb(包括UDP首部).
然而64kb在当今的互联网环境下,是一个非常小的数字.
一旦数据超过64kb,就可能导致数据被截断,就可能对公司造成损失.
到这里可能有人就会想到,如果把UDP的长度字段,扩展一下,不就行了?
- 听起来确实是一个好方法,但是实际上,这是这是非常不靠谱的,不靠谱不是"技术问题",而是"政治问题".
作为一个"网络协议"不是单方面修改就可以的,即使修改了你的服务器的内核中UDP的实现,可是,客户端那边,用户的电脑上,咋办???
服务器要改,客户端也要改,客户端你咋改??
就算你真的把用户的系统都改了,但是人家用户也不只是用你的服务器啊,还要用别人的啊.
除非你能够把全世界所有的PC/手机/服务器所有涉及到UDP协议的地方,都进行统一修改.
相比于修改UDP,不如发明出一个新的协议来代替UDP,可能更简单一些~
校验和
前置知识
在网络传输的过程中,是非常容易出现错误的~
电信号/光信号/电磁波 如果收到环境的干扰,可能就会使里面传输的信号发生改变.(高中物理就教过我们,电厂/磁场 都是能相互影响的)
为了能够"发现"或者"纠正"这里出现的错误,于是我们引入了"校验和".
校验和具体是如何工作的?
校验和可以在要传输的数据中,引入额外信息,用来发现/纠正传输数据的错误.
在UDP中,使用2个字节,作为校验和.
UDP使用简单有效的方案,CRC校验和(循环冗余校验).
更具体一点,就是把UDP数据报里的整个数据,都进行遍历,分别取出每个字节,往一个两个字节的变量上进行累加,由于整个数据可能很多,加着加着可能使结果溢出了,但是溢出也没关系,重点不在于最终的和是多少,而是关心校验和的结果是否会在传输过程中发生改变.
接收方就可以根据数据的内容,按照同样的算法再算一遍校验和,得到checksum2.
如果传输的数据在网络通信过程中没有发生任何改变,此时算出来的checksum1 == checksum2.
反之,如果发现checksum1 != checksum2,我们就可以认为数据在网络传输过程中出错了.
在计算校验和的过程中,是否可能出现两个不同的数据,生成的校验和相同呢?
这个是可能会存在的,但是概率特别低.
这个问题对于CRC来说,概率可能比其他方案高一点.
除了CRC之外,还有一些其他的算法来实现校验和,比如MD5和SHA1.
MD5算法,本质上是一个"字符串hash算法",它背后的实现过程是一个"数学过程",我们可以简单理解为套公式~
相比于MD5的计算细节,我们更关心它的特点[重点掌握]:
- 定长: 无论输入的字符串,长度多长,算出的MD5的结果都是固定长度.(适合做校验和算法)
- 分散: 输入的内容,哪怕只有一点点发生改变,经过计算得到的MD5值都会相差很大.(适合做hash算法)
- 不可逆: 根据输入内容,计算MD5,非常简单,但是如果已知MD5值,还原出原始的内容,这在理论上是不可行的.(适合作为加密算法)
说个题外话,MD5解密网站,并非是真的解密,而是它把大量常见的字符串MD5值,提前通过哈希表的方式存储好了.
MD5不可逆(不止MD5还有其他很多加密算法)都是建立在人类当下的算力水平之上的.破解的计算量非常非常大,使用当前人类最厉害的计算机,也要连续算几十年,几百年…
本文到这里就结束啦~