网络原理 - 3(UDP 协议)

目录

协议

应用层

xml

json

protobuffer

传输层

端口号(Port)

UDP 协议

UDP 协议端格式

完!


协议

网络通信中,协议是一个非常重要的概念。我们前面在网络原理中,就已经介绍了,为了统一各方网络,大佬们提出了协议,因为协议太多,对其进行了分层。

应用层

应用层,对应着应用程序,是跟我们程序员打交道最多的一层。调用系统提供的网络 API 写出的代码,都是属于应用层的。

应用层这里当然也有很多现成的协议,但是更多的,还是需要我们程序员根据实际的业务场景,自定义协议(网络传输的数据要怎么使用,当然也要考虑到数据是什么样的格式,里面包含那些内容~)

协议,其实就是一种与欸的那个,虽然存在很多的现有的协议(大佬们已经搞好了的),除此之外,我们程序员也可以自己来约定协议。

自定义协议,一般要约定好两方面的内容:

1. 服务器和客户端之间要交互那些信息

2. 数据是具体格式

(客户端按照上述约定发送请求,服务器按照上述约定来解析请求)

(服务器按照上述约定构造响应,客户端按照上述约定来解析响应)

举个栗子:

住酒店:

打开出行相关的 APP,显示出主页,主页里面就很显示出一些酒店的列表。

而且这些酒店都是在我们附近的(打开软件的时候,需要把我们的位置,告诉服务器)

显示的酒店列表中,也会包含一些信息 -- 酒店的名称 细节图片 相关评分 相关简介...

上述的这些信息,要按照什么样的格式来进行组织呢???是有一些固定的套路的~~~

确定如何组织数据格式这件事情,往往是需要客户端的程序员和服务器的程序员,这两伙人坐在一起,一起把这个事情给确定下来~~~(这里的格式怎么样约定都可以,只要是两伙程序员达成共识即可~~~)

一个简单粗暴但五脏俱全的栗子~~~

1. 请求,约定使用行文本的格式来进行表示:

userId,position\n               (一个请求以 \n 为结尾,多个字段之间只用 , 来进行分割)

比如(1003,[经纬度]\n)

2. 响应,也是使用行文本来表示,一个响应中可能会包含多个酒店,每个酒店占一行,每个酒店都要返回 id,名称,图片,评分,简介

比如( 2001,A 酒店,[logo图片地址],4.9,五星级酒店\n

            2002,B酒店,[logo图片地址],4.5,干净卫生的民宿\n

           \n)

(若干行的最后,使用空行来作为所有数据的结束标志,上面的这一系列内容就是同一个响应中的数据了)

补充:

客户端和服务器之间往往要进行交互的是”结构化数据“(交互的数据是一个结构体 / 类,其中会包含很多个属性)网络传输的数据其实是”字符串“”二进制 bit 流“。

协议约定的过程,就是把结构化数据转换成字符串 / 二进制 bit 流的过程。

把结构化数据,转成字符串 / 二进制 bit 流,这个操作,称为”序列化“

把字符串 / 二进制 bit 流还原成结构化数据,这个操作,称为”反序列化“

序列化 / 反序列化具体要组织成什么样的格式,这里要包含那些信息,预定这两件事情的过程,就是自定义协议的过程。

为了让程序员更方便的去约定这里的协议格式,业界给出了几个比较好用的方案:

xml

大概的模样如下:

<> 称为标签(tag),一般都是成对出现的,分别为开始标签和结束标签。开始标签和结束标签中间夹着的就是标签的值,标签是可以嵌套的。(标签的名字 / 标签的值 / 标签的嵌套关系,都是程序员自定义的~)

xml 约定

优点:使得数据内容的可读性和拓展性都提升了很多,标签的名字能够对数据起到说明作用,后续要再增加一个属性,新添加一个标签即可,对已有代码影响不大~

缺点:冗余信息比较多,标签的描述性信息,占据的空间反而比数据本身还要多了~

json

大概的模样如下:

采用的是键值对结构:

键和值之间用:进行分割,键值对之间用 , 进行分割。

把若干个键值对使用 {  }  括起来,此时就形成了一个 json 对象,还可以把多个 json 对象放到一起,使用 , 分隔开,并且整体使用 [ ] 括起来,就形成了一个 json 数组。

json 约定:

优点:可读性,扩展性都很好,而且对比 xml 来说,占用的空间更少了。

缺点:虽然 json 的确比 xml 占用的空间更少了,节省了宽带,但很明显,这里的宽带仍然还是有浪费的部分的,尤其是这种数组格式的 json,这种情况下往往传输的数据字段都是相同的,很多 key 关键字都是被重复传输的(id,name 等等...)

protobuffer

这种约定是更加节省宽带的方式,也是效率最高的方式。

protobuffer 只是在开发阶段(代码)定义出这里都有那些资源,描述每个字段的定义。程序真正运行起来的时候,实际传输的数据是不包含这些描述信息的。这样的数据都是按照二进制的方式来进行组织的。

这种方式虽然程序运行的效率会非常高,但其实并不太有利于程序员阅读~~~

虽然 protobuffer 运行效率更高,但是使用并没有比 json 更加广泛,只有一些对于性能要求非常搞的场景,才会使用 protobuffer。

应用层也很多线程的协议,HTTP 这种 后面详细介绍~

传输层

传输层中,虽然是系统内核已经实现好了的,但我们仍然需要重点进行关注,我们之前在网络编程中,使用的 socket API 就是传输层提供的

端口号(Port)

端口号,是一个 2 字节的整数。标识了一个主机上进行通信的不同的应用程序。

在 TCP/ IP 协议中,用源 IP,源端口号,目的 IP,目的端口号,协议号,这样一个五元组来标识一个通信。

端口号范围划分:

0 - 1023:是一些知名端口号,HTTP,FTP,SSH 等这些广为使用的应用层协议,他们的端口号的固定的。

1024 - 65535:操作系统动态分配的端口号。我们前面在网络编程中,客户端程序的端口号,就是由操作系统在这个范围内分配的。

一些有名的端口号:

SSH 服务器:22 端口

FTP 服务器:21 端口

telnet 服务器:23 端口

HTTP 服务器:80 端口

HTTPS 服务器:443 端口

我们写程序使用端口号的时候,需要避开这些知名端口号~

UDP 协议

前面我们已经提过,UDP 协议的四个特点:无连接,不可靠传输,面向数据报,全双工。

研究一个协议,我们主要是研究报文格式,基于报文格式,来了解这个协议的各个特性。

UDP 数据报 = 报头(重点) +  载荷(应用层数据包)

UDP 协议端格式

上面的这个图,并不准确,是为了我们书籍教材排版方便做出的妥协,其实应该是下面这样的:

UDP 报头中,一共有 4 个字段,每个字段 2 个字节(一共 8 个字节)

由于 UDP 协议中使用 2 个字节(16 位)来标识端口号,端口号的取值范围就是 0 - 655335(即这里最大值就是 64KB(2^10 = 1 KB),即,一个 UDP 数据报最大的长度,就是 64 KB,没办法更长了),一旦整个数据报的长度超出 64 KB,此时就可能导致数据出现阶段(数据后面的部分就没有了)

(总的 UDP 数据报最大长度是 64KB,则载荷部分实际能承担的最大长度,应该是 64KB - 8(减去报头的长度))

为了解决数据被截断的问题,有两个方案。

方案一:在应用层,把数据报进行拆分,之前一个数据报表示 N 个页面,拆分成每一个页面占用一个 UDP 数据报,甚至可以进一步的拆分成,一个页面对应多个 UDP 数据报。(开发和测试的成本都很大~~)

方案二:使用 TCP 代替 UDP,TCP 没有上述的长度限制~~

那为什么,不进行扩展呢???将 UDP 数据报,扩展成 4 个字节的长度呢???

技术上很容易实现,但要改,就要所有的系统一起改,如果一方改了,另一方不该,相互之间就无法进行通信了~~~大家都僵持住了...

校验和:验证数据在传输过程中是否正确~~~

前提是:数据在网络传输的过程中,是可能出错的!

网络数据传输:本质上其实是光信号 / 电信号 / 电磁波进行传输

上述信号都是很可能收到干扰的。

比如,使用高低电平来表示 0 1,外界如果加上一个磁场,就有可能把高电平变为低电平,低电平变为高电平,此时, 0 -> 1,1 -> 0 出现了比特翻转。现代的传输体系,其实有一系列的保护机制,来减少外界的干扰。

校验和的作用就是用来识别出当前的数据是否在传输过程中出现错误。

注意:网络中的校验和,并非是简单的按照数据的长度 / 数量来作为标准进行校验的,一定是数据的内容会参与到其中。

严格的来说,校验和只能用来“证伪”,即,只能是证明数据是出错了,没办法确保这个数据 100% 是正确的。但是实践中可以近似的认为检验和一致,数据就一致了。

UDP 中,校验和是使用比较简单的方法 - CRC 算法来完成校验的(循环冗余校验)

比如,要产生一个两字节的校验和:

加的过程中,产生的数据可能会比较大,超出了 short 两个字节的范围,溢出了,其实也无妨,这里不用管。

UDP 数据报发送方,在发送数据之前,先计算一边 CRC,把算好的 CRC 值放到 UDP 数据报中。(设这个 CRC 值为 value1)

接下来,这个数据报会通过网络传输到达接收端,接收端收到这个数据之后,也会按照同样的算法,再算一次 CRC 的值,得到的结果是 value2。比较自己计算的 value2 和收到的 value1 是否一致。如果是一致的,就说明数据大概率是 ok 的。如果不一致,则传输过程中一定出现了错误。

上述 CRC 算法,为什么说 value1 和 value2 如果是一致的,数据大概率是 ok 的呢???如果只有一个 bit 位发生反转,则 CRC 100% 能够发现错误。但如果恰好有两个 / 多个 bit 位发生反转,有可能恰好校验和仍然和之前的一样~~~(这种情况比较低,可以忽略不计,但如果希望这里有更高的检查精度,就需要使用其他更为严格的校验和算法了)

md5 算法,md5 算法的背后,是有一系列的数学公式来进行计算的,此处不讨论数学公式,来重点认识一下特点:

1. 定长:无论原始数据有多长,算出来的 md5 的最终值都是一个固定长度(md5 有 16 位版本,也有 32 版本,也有 64 位版本)

2. 分散:计算 md5 的过程中,原始数据,只要变化一点点,其算出来的 md5 值就会发生很大的变化差异。(这样的特性,使得 md5 也可以作为一个字符的 hash 算法)

3. 不可逆:给一个源字符串,计算 md5 值,过程非常简单(比 CRC 复杂一些,但整体比较简单)但是如果给一个算好的 md5 值,还原为原始的字符串,理论上无法完成~

原始的字符串 ==》 md5 这个过程,会有很多信息量损失了,无法直接还原~

(一些在线解密 md5 的网站,本质上是通过“打表”的方式完成 --> 服务器在不停的计算各种字符串的 md5 值,然后存储下来,我们输入 md5 值,他就直接去数据库里面查询 == 》 只能破解出一些常见的一般的字符串的 md5值~)

完!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/80367.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java Agent 注入 WebSocket 篇

Agent 如果要对其进行Agent注入的编写&#xff0c;需要先理解三个名字premain&#xff0c;agentmain&#xff0c;Instrumentation premain方法在 JVM 启动阶段调用&#xff0c;一般维持权限的时候不会使用 agentmain方法在 JVM 运行时调用 常用的 Instrumentation实例为代理…

【深度强化学习 DRL 快速实践】近端策略优化 (PPO)

PPO&#xff08;2017&#xff0c;OpenAI&#xff09;核心改进点 Proximal Policy Optimization (PPO)&#xff1a;一种基于信赖域优化的强化学习算法&#xff0c;旨在克服传统策略梯度方法在更新时不稳定的问题&#xff0c;采用简单易实现的目标函数来保证学习过程的稳定性 解决…

笔试强训:Day2

一、字符串中找出连续最长的数字串(双指针) 字符串中找出连续最长的数字串_牛客题霸_牛客网 #include <iostream> #include <string> #include <cctype> using namespace std;int main() {//双指针string str;cin>>str;int nstr.size();int begin-1,l…

MySQL 详解之 InnoDB:核心特性深度剖析 (ACID, 事务, 锁, 外键, 崩溃恢复)

在 MySQL 的世界里,存储引擎是数据库管理系统的核心组成部分,它负责数据的存储和提取。MySQL 支持多种存储引擎,如 MyISAM, Memory, CSV 等,但自 MySQL 5.5 版本以来,InnoDB 成为了默认的存储引擎,也是绝大多数应用场景的首选。 为什么 InnoDB 如此重要并被广泛采用?因…

Java中正则表达式使用方法

1. 正则表达式概述 正则表达式&#xff08;Regular Expression&#xff0c;简称 Regex&#xff09;是一种用于匹配字符串的模式工具。在 Java 中&#xff0c;正则表达式通过 java.util.regex 包实现&#xff0c;主要涉及以下两个类&#xff1a; Pattern&#xff1a;表示一个编…

使用浏览器的Clipboard API实现前端复制copy功能

在前端开发中&#xff0c;复制文本到剪贴板的功能通常使用浏览器的 Clipboard API 实现。比如 navigator.clipboard.writeText 方法。以下是一个简单的案例&#xff0c;展示如何使用 Clipboard API 实现复制文本的功能。 基本用法 首先&#xff0c;你需要创建一个按钮&#x…

【因果推断】(二)CV中的应用

文章目录 因果表征学习因果图 (Causal Diagram)“后门准则”&#xff08;backdoor criterion&#xff09;和“前门准则”&#xff08;frontdoor criterion&#xff09;后门调整Visual Commonsense R-CNNCausal Intervention for Weakly-Supervised Semantic SegmentationCausal…

【iOS】alloc init new底层原理

目录 前言 alloc alloc核心操作 cls->instanceSize(extraBytes) calloc obj->initInstanceIsa init 类方法&#xff1a; 实例方法&#xff1a; new 前言 笔者最近在进行对OC语言源码的学习&#xff0c;学习源码的过程中经常会出现一些从来没有遇见过的函数&…

QT窗口相关控件及其属性

widget&#xff0c;PushButton&#xff0c;lineEdit等都是基于QWidget延展出来的 并不是完整的窗口&#xff0c;而是作为窗口的一部分 真正的窗口是QMainWindow 菜单栏 Qt中的菜单栏是通过QMenuBar这个类来实现的&#xff0c;一个主窗口最多只有一个菜单栏&#xff0c;位于主…

day47—双指针-平方数之和(LeetCode-633)

题目描述 给定一个非负整数 c &#xff0c;你要判断是否存在两个整数 a 和 b&#xff0c;使得 a^2 b^2 c 。 示例 1&#xff1a; 输入&#xff1a;c 5 输出&#xff1a;true 解释&#xff1a;1 * 1 2 * 2 5示例 2&#xff1a; 输入&#xff1a;c 3 输出&#xff1a;f…

蓝桥杯 20. 压缩变换

压缩变换 原题目链接 题目描述 小明最近在研究压缩算法。他知道&#xff0c;压缩时如果能够使数值很小&#xff0c;就能通过熵编码得到较高的压缩比。然而&#xff0c;要使数值变小是一个挑战。 最近&#xff0c;小明需要压缩一些正整数序列&#xff0c;这些序列的特点是&a…

element-ui多个form同时验证,以及动态循环表单注意事项

多个form同时验证&#xff1a; validateForm(refs) {if (!refs) {return false}return new Promise((resolve, reject) > {refs.validate().then((valid) > {resolve(valid)}).catch((val) > {resolve(false)})}) }, async handleConfirm() {Promise.all([this.valid…

Spring Boot中自定义404异常处理问题学习笔记

1. 问题背景 在Spring Boot项目中&#xff0c;需要手动返回404异常给前端。为此&#xff0c;我创建了一个自定义的404异常类UnauthorizedAccessException&#xff0c;并在全局异常处理器GlobalExceptionHandler中处理该异常。然而&#xff0c;在使用Postman测试时&#xff0c;…

你学会了些什么220622?--搭建UI自动化

jenkins访问地址&#xff1a;http://192.168.82.129:8080/ 账号密码&#xff1a;admin/a123456a ***** 什么是UI自动化** 使用工具或者脚本对需要测试的软件的前端界面在预设的条件下&#xff0c;在已有的测试数据下运行系统或者应用程序&#xff0c;并获取其前端页面UI显示的…

【2025计算机网络-面试常问】http和https区别是什么,http的内容有哪些,https用的是对称加密还是非对称加密,流程是怎么样的

HTTP与HTTPS全面对比及HTTPS加密流程详解 一、HTTP与HTTPS核心区别 特性HTTPHTTPS协议基础明文传输HTTP SSL/TLS加密层默认端口80443加密方式无加密混合加密&#xff08;非对称对称&#xff09;证书要求不需要需要CA颁发的数字证书安全性易被窃听、篡改、冒充防窃听、防篡改…

JavaFX 第一篇 Hello World

1、简介 JavaFX 是一个用于构建客户端应用程序的 Java 库&#xff0c;作为 Java 标准库的一部分&#xff08;JDK 8 到 10&#xff09;&#xff0c;从 JDK 11 开始&#xff0c;JavaFX 将以独立模块发布&#xff0c;将不再包含在 JDK标准库中&#xff0c;他是 Java 应用程序开发的…

SQL实战:02之连续数问题求解

文章目录 概述题目:体育馆的人流量题解步骤一&#xff1a;构造出一个连续序列步骤二&#xff1a;找出符合条件的组的序号步骤三&#xff1a;fetch结果&#xff0c;使用内连接过滤出符合条件的记录。完整SQL 题目二&#xff1a;连续出现的数字题解步骤一&#xff1a;分区并构建连…

STM32 的 GPIO和中断

GPIO的简单介绍 内部结构 施密特触发器&#xff08;TTL肖特基触发器&#xff09; 的工作原理&#xff1a; 施密特触发电路&#xff08;简称&#xff09;是一种波形整形电路&#xff0c;当任何波形的信号进入电路时&#xff0c;输出在正、负饱和之间跳动&#xff0c;产生方波或…

Server - 优雅的配置服务器 Bash 环境(.bashrc)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/147335592 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 登录服…

使用PyTorch实现图像增广与模型训练实战

本文通过完整代码示例演示如何利用PyTorch和torchvision实现常用图像增广方法&#xff0c;并在CIFAR-10数据集上训练ResNet-18模型。我们将从基础图像变换到复杂数据增强策略逐步讲解&#xff0c;最终实现一个完整的训练流程。 一、图像增广基础操作 1.1 准备工作 #matplotli…