UDP 的报文结构和注意事项

如何自定义一个协议

先有一个需求,有个场景,打开外卖软件,会显示商家列表,列表中有很多项,每一项都包含了一些信息,商家的名称,图片,好评率,距离你的位置,评分

这些信息都是通过网络,从服务器获取的,

客户端,需要给服务器发送一个请求,服务器收到请求之后,就给客户端返回一个响应,这里的请求和响应该如何创建呢,格式是怎样的呢?

我们可以做出如下设计:

1.明确当前请求和响应中包含哪些信息

请求:用户身份,用户当前位置

响应:商家的名称,图片,好评率,距离你的位置,评分

2.明确具体的请求和响应的格式

示例1:

请求:1234,23 100\n

所谓的明确格式就是看你按照什么样的方式,构造出一个字符串,后续这个字符串就可以作为udp或者tcp的payload进行传输,另一方面,服务器就可以对这个字符串进行分析,解析出逗号前面是用户身份,逗号后面是用户当前位置(经纬度)

响应:

老麻抄手,1.jpg,96%,1.3km,4.6\n

这个时候就构造出了一个响应这样的字符串,用户就可以按照这样的格式来进行解析了

网络上,传输的数据,本质上就是字符串,因为无法直接传输传输一个java对象这样的内容

java写代码,都是使用的各种对象,但是最后在发送数据的时候,就需要把对象转换为二进制的字符串(序列化)

而在接收数据的时候,也需要把二进制的字符串转换为对象(反序列化)

实际上,上述这样的约定,可以随意构造,只要保证,客户端和服务器遵守同一个约定即可

示例2:

鱼香肉丝;1.jpg;96%;2.6km;4.5!

使用!来分割每个商家,使用;来分割商家的每个信息

通用的协议格式

虽然说,自定义的协议格式,是可以任意的,但是为了避免出现过于天马行空的设计,大佬们就做出了一些通用的协议格式,参考这些格式,就可以对咱们的协议设计产生重要的指导作用

xml

是以成对的标签,来表示"键值对"信息,同时标签支持嵌套,就可以构成一些更为复杂的树形结构数据

请求:

< request>

< userId>1234< /useId>

< position>100 80< /position>

< /request>

对象的本质上也是键值对,属性的名字就是键,属性的值就是值

html是写网页的语言,也是带有标签的

xml里的标签都是程序员自定义的,html里的标签,都是有一套标准规定好的

响应:

< response>

< shops>

< shop>

< name>老麻抄手< /name>

< image>1.jpg< /image>

< distance>1km< /distance>

< rate>96%< /rate>

< star>4.7< /star>

< /shop>

< shop>

< name>鱼香肉丝< /name>

< image>1.jpg< /image>

< distance>2km< /distance>

< rate>94%< /rate>

< star>4.6< /star>

< /shop>

< /shops>

< /response>

优点:xml非常清晰的把结构化数据表示出来了

缺点:表示数据需要引入大量的标签,看起来非常繁琐,同时也占用了不少的网络带宽

国内,最贵的硬件资源,就是网络带宽

json

最流行的一种数据组织格式

本质上也是键值对,看起来比xml要干净不少

请求:

{

useId:1234,

position:"100 80"

}

json中,使用{}表示键值对,使用[]表示数组,数组里的每个元素,可以是数字,可以是字符串,也可以是其他的{},[]

响应:

{ name:'老麻抄手', image:'1.jpg', distance:1km, rate:96%, star:4.7 }, name:'鱼香肉丝', image:'1.jpg', distance:2km, rate:97%, star:4.5

当前最主流的一种网络数据传输的格式,未来实际开发中经常会用到json格式的数据

json对于换行并不敏感,如果这些内容全部都放在同一行,也是完全合法的

一般网络传输的时候,会对json进行压缩(去掉不必要的换行和空格),同时把所有的数据放到一行去,整体占用的带宽就更低了,但是会影响到可读性

protobuffer

谷歌提供的一套,二进制的数据序列化方式

使用二进制的方式,约定某几个字节,表示哪个属性

最大程度上节省了空间(不必传输key,根据位置和长度,区分每个属性)

优点:

节省带宽,最大化优化效率

缺点:二进制数据,肉眼无法直接观察,不方便调试

使用起来也是比较复杂的,需要专门编写一个proto文件,描述数据的格式咋写,proto需要一系列的语法,有点像java/c++又不太一样,再进一步的通过proto提供的工具,把proto文件转化成一些代码,再嵌入到程序中使用,这个主要用于对于性能要求更高的场景

对于一个程序来说,开发效率/运行效率哪个更重要

通常来说,是开发效率更重要,可以通过提升硬件设备,来提高运行效率,想要提高开发效率,就得招聘更多的程序员,成本开销更大

当然,在类似游戏开发的场景,就是需要运行效率更高比较重要

UDP协议

UDP的协议格式

端口号的有效范围是两个字节,也就是0-65535

但是,1-1024这个范围的端口号,是被系统赋予了特定的含义,一般也不建议使用,使用需要管理员权限

同样,UDP报文长度也是两个字节,换算单位,也就是64kb,也就是一个UDP数据报的最大长度就是64kb

校验和是为了检查数据在传输的过程中,是否出错,因为数据在传输的过程中,本质上是光信号和电信号的传输,而这些信号,容易收到外界的干扰和影响,比如磁场,太阳耀斑等,可能会出现,本来传输的是0,结果传输的是1,此时,数据的传输错误了,接收方在接受到数据之后,就需要先确认一下,这个数据是否是一个错位的数据,而校验和就是一个简单有效的方式

UDP校验和究竟是怎么实现的,它使用了一种简单粗暴的CRC校验算法(循环冗余检验和)

把UDP数据报中的每个字节,都依次进行累加,把累加的结果,保存到2个字节的变量中,可能会溢出,溢出也无所谓,最终就得到了一个校验和,

传输数据的时候,同时也会将原始数据和校验和一起传输过去,接收方收到数据,同时也会收到传输过来的校验和,接收方会按照同样的方式再计算一遍,得到新的校验和,比较新旧校验和是否相等,但是这里就算新旧校验和相等,也不代表数据传输就一定吗没有问题

相关推荐
云云32137 分钟前
亚矩阵云手机针对AdMob广告平台怎么进行多账号的广告风控
大数据·网络·线性代数·游戏·智能手机·矩阵
小墙程序员38 分钟前
一文了解网络连接的完整流程
网络协议·tcp/ip
网安INF1 小时前
CVE-2020-1938源码分析与漏洞复现(Tomcat 文件包含/读取)
java·网络·web安全·网络安全·tomcat·漏洞复现
nice_evil2 小时前
华为Openeuler/Linux/CentOs 网络配置及故障排查/远程连接设置ssh/ibmc等问题及解决方案合集
linux·网络·centos·openeuler·网络配置与激活
风清再凯3 小时前
docker 网络
网络·docker·容器
沐土Arvin4 小时前
三次握手建立连接,四次挥手释放连接——TCP协议的核心机制
java·网络·tcp/ip
游戏开发爱好者84 小时前
iOS App上线前的安全防线:项目后期如何用Ipa Guard与其他工具完成高效混淆部署
websocket·网络协议·tcp/ip·http·网络安全·https·udp
Amy.Wang4 小时前
常见的网络协议有哪些
网络·网络协议
Mountain and sea4 小时前
ABB RobotStudio 和 S7-PLCSIM Advanced V5.0 搭建虚拟通信环境,实现 PLC 对机器人布尔量、数字量和模拟量的控制。
网络·机器人
心月狐的流火号5 小时前
Java网络编程深度解析:TCP与UDP如何共享同一端口
网络协议