【TCP/IP】自定义应用层协议,常见端口号

简介: 【TCP/IP】自定义应用层协议,常见端口号

互联网中,主流的是 TCP/IP 五层协议

  • 5G/4G 上网,是有自己的协议栈,要比 TCP/IP 更复杂(能够把 TCP/IP 的一部分内容给包含进去了)

应用层

可以代表我们所编写的应用程序,只要应用程序里面用到了网络通信,就可以认为这个代码就是属于应用层的代码

日常开发中最常用到的一层:

  1. 使用大佬们已经创建好的应用层协议
  • 应用层知名的协议有很多,其中的佼佼者就是 HTTP
  1. 自己定义应用层协议
  • 另外四层都是操作系统/硬件/驱动已经实现好了的,我们不可能“自定义”,只能使用人家的

协议就是约定

  • 按照自己的规则,约定通讯方式——>自定义应用层协议

自定义应用层协议

自定义应用层协议,具体要做什么事情:

明确要传递的信息

  1. 明确前后端交货过程中,要传递哪些信息

举个例子:开发一个外卖软件,打开软件后,首先需要展示一个“商家列表”

此处就需要先确定传递的信息是什么

  1. 请求:用户是谁(用户的 ID),用户所处的位置
  2. 响应:商家列表,包含多个商家,每个商家信息中,又有商家的名字、图片、距离、评分

这里的信息如何确定,都是根据当前的需求来产生的

明确组织信息的格式

  1. 明确组织这些信息的格式
    针对信息组织格式,也有很多种方式,使用哪种方方式都可以,只要确定前段和后端是同一种方式就可以了

举个例子:使用行文本的方式来组织上述数据

  1. 请求:用户id,用户位置\n
  2. 响应:商家的id,商家名称,商家的图片地址,商家的距离,商家的评分\n

关于组织数据的格式,还有一些说法,上述“行文本”简单粗暴的方案,在实际开发中,很少会这样做


XML 方案

Maven 中就会见到,通过“成对的标签”表示“键值对”信息

<request>
  <userid>1001</userid>
  <postion>E45N60</postion>
</request>
  • 可以通过 XML 来传输网络数据,也可以作为程序的配置文件
  • 不过XML进行网络传输的时候,又有一个明显的缺点——会消耗大量的带宽
  • 网络通信中,带宽是一个非常贵的硬件设备
  • 在传输标签的时候,都得传输成对的标签,传入的信息更多
  • 所以现在 XMl 一般都是在配置文件,不进行网络传输了
  • XMl 里面的标签(键值对)都是程序员固定的,而 HTMl 里面的标签都是固定的(已经有一套标准,约定好哪些标签是合法标签,这些标签都是什么含义)

JSON 方案

当前主流的网络通信的数据格式,相比 xml 来说,可读性是很好的,同时能节省一定的带宽

{
  "userid":1001,
  "postion":""E45N60"
}
  • JSON也是“键值对”格式,
  • 键和值之间用 : 分割
  • 键值对之间用 , 分割
  • 所有的键值对,都使用 {} 括起来
  • 这里的标签都只有一份,不需要结束标签了,节省了传递开销

YML(YAML)方案

强制要求了数据组织的格式,强制要求写成“可读性非常高”的格式

  • 键值对必须独占一行
  • “嵌套”结构必须通过缩进来表示

protobuffer方案

前三个方案,都是关注可读性,而 protobuffer 关注性能,牺牲了可读性(通过二进制的方式组织数据)

  • protobuffer 直接通过“位置”约定字段的含义,不需要传输 key 的名字,也会针对传输的数值,进行二进制的编码,起到一些“压缩”的效果
  • 极大地缩减了要传输的数据的体积——>带宽消耗就越小——>效率越高
  • 但二进制数据无法肉眼阅读,调试相关程序的时候,就会比较麻烦

常见端口号

端口号是一个整数,用来区分不同的进程。

  • 同一时刻,同一个机器上,同一个协议,一个端口号只能被一个进绑定
  • 一个进程可以绑定多个端口号
  • 端口号是通过两个字节的无符号整数表示的,取值范围 0~65535,但实际上 0 比较特殊,一般不会使用
  • 1~1023 属于已经被预定好的(有一些知名的服务器,已经提前预定了这个端口),这样的端口称为“知名端口号”(其实里面的大部分服务器已经不再使用了,在 80、90 年代是知名的)
  • 我们日常开发的时候,会避开这些端口

业务端口和管理端口

什么时候会涉及到一个进程(服务器)绑定多个端口?

  • 编写服务器,肯定需要先绑定至少一个端口号,和客户端进行交互(称为“业务端口”)
  • 服务器运行过程中,希望能够对这个服务器的行为,进行一些“控制”
  • 比如让服务器重新加载某个数据/某个配置/修改服务器的某个功能
  • 也可以通过网络通信完成上述功能
  • 就可以让服务器绑定另一个端口,通过这个端口,编写一个客户端,给服务器发送一些“控制类“请求
  • 上面的“另一个端口”就是“管理端口

调试端口

当需要针对服务器运行状态进行检测和调试,需要查看服务器运行中某个关键变量的数值的时候,千万不能用调试器来进行调试,一旦使用调试器调试这个服务,就会使服务器的一些线程被阻塞住,无法给客户端正确提供服务了

  • 虽然可以通过日志进行打印,但是不方便,需要修改代码并重启服务器
  • 可以让服务器绑定另一个端口,然后实现一些相关的打印关键变量的逻辑,客户端发送对应的调试请求
  • 这里的“另一个端口”就是“调试端口

长连接和短连接

长连接

客户端连上服务器之后,一个连接中,会发起多次请求,接收多个响应

  • 一个连接到底进行多少次请求是不确定的,Echo Client 就是这种模式

短连接

客户端连上服务器之后,一个连接只发一个请求,然后就断开连接了

UDP 协议报头

学习一个网络协议,主要就是学习“数据格式”/“报文格式

源端口/目的端口

  • 端口号是属于传输层的概念
  • UDP 报头使用两个自己的长度来表示端口号
  • 之所以端口号的范围是 0~65535,是因为底层网络协议做出了强制要求
  • 如果使用一个 10 w 这样的端口,就会在系统底层被“截断”
  • UDP 并不关心后面的正文里面是什么数据,只需要关心报头里面是怎么组织的
  • 报头里面分为四个部分,每个部分固定是两个字节(16 bit),里面没有分隔符,就是通过固定长度来进行区分的

网络通信中,涉及到四个关键信息:源 IP/目的 IP源端口/目的端口

  • 源端口:发出数据报那个程序使用的端口号——>发件人电话
  • 目的端口:接受这个数据报的程序使用的端口号——>收件人电话
  • 源 IP:发出数据报那个程序的 IP——>发件人地址
  • 目的 IP:接受这个数据报的程序的 IP——>收件人地址

UDP报文长度

UDP报文长度:报头长度 + 载荷长度

  • 长度单位是字节,
  • 比如,报文长度 1024,——>整个 UDP 数据报就是 1024 字节;由于是两个字节来表示这个长度,所以最大值 65535——64 KB(65536/1024)
  • 64 KB 放在今天,是个很小的数字,所以如果使用 UDP 协议传输一个很大的数据,就会变得很麻烦

UDP 用了好多年,一直挺好用,但随着业务的发展,广告越来越多,越来越复杂,导致一个网络响应数据报的体积越来越大,逐渐逼近 64 KB。一旦数据超过了 64 KB,就可能到值数据被截断,这样广告可能就无法正常显示了。对于这样的情况,有两个解决方案:

  1. 把一个大的数据报,拆分成多个,分别进行传输
  • 很快就被否决了;因为实现分包、组包的过程非常复杂,充满了不确定性
  1. 直接使用 TCP
  • TCP 对于长度没有限制,其自身也带有可靠传输这样的机制,对于整体的通信质量来说也是有利的
  • 代码的修改成本比较低

校验和

前提:网络传输过程中,非常容易出现错误

  • 电信号/光信号/电磁波——>收到环境的干扰,使里面传输的信号发生改变

校验和存在的目的,就是为了能够“发现”或者“纠正”这里的错误。就可以给传输的数据中,引入“额外信息”,用来发现/纠正传输数据的错误

  • 这里的额外信息就是 checksum
  • 如果只是发现错误,需要携带的额外信息,就可以少一些(发现就会丢弃掉,不会让对方重发)
  • 如果是想要纠正错误,携带的额外信息就要更多(消耗更多带宽)

举个例子:你妈让你去买菜,西红柿、鸡蛋、茄子、晃过,最后补充一句“一共四样”

  • 这里的“一共四样”起到的作用就相当于是“校验和”。通过“一共四样”你可以对手里的菜进行检查,有没有买多、买少

但这样的“校验和”并不能准确的识别出问题,而且容易误判。所以我们希望校验和可以更严格地检查数据的内容,可以结合内容/内容的片段来生成校验和

  • 比如你在默写金庸先生的十五部作品的名称,写完后,你可以通过“飞雪连天射白鹿,笑书神侠倚碧鸳”这一幅对联和你写的书名的第一个字对一下,若能对象,就说名此处的名字都是正确的
  • 这样的校验和就是基于内容来进行校验的
  • 虽然出错的数据恰好没有被校验出来,这可情况也是可能会发生的
  • 但是一个良好的校验和算法,可以让上述问题发生的可能性非常低

CRC 校验和(循环冗余校验)

把 UDP 数据报整个数据都进行遍历,分别取出每个字节,往一个两个字节的变量上进行累加

  • 由于整个数据可能会很多,所以加着加着可能就结果溢出了,但溢出也没关系
  • 我们重点关心的不是最终加和是多少,而是校验和结果是否会在传输中发生改变

例如:我们去传输一个 UDP 数据报

  • 发送方整合整个 UDP 数据,基于这些数据,计算得到一个 checksum1
  • 接收方收到的数据:
  1. 数据的内容
  2. 校验和 checksum1
  • 接收方就可以根据数据的内容,按照同样的算法,再算一遍校验和,得到 checksum2
  • 如果传输的数据在网络通信过程中,没有发生任何改变,则一定有 checksum1 == checksum2

MD5 算法

本质上是一个“字符串 hash 算法”

特点

  1. 定长:无论输入的字符串长度多长,算出的 MD5 的结果都是固定长度——>适合做校验和算法
  2. 分散:输入的字符串哪怕只有一点点发生改变,得到的 MD5 的值都会相差很大——>适合做 hash 算法
  3. 不可逆:根据输入内容,计算 MD5 非常简单,但是如果想通过 MD5 值还原出原始的内容,理论上是不可行——>适合作为加密算法


相关文章
|
24天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
16天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
20天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2577 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
18天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
3天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
2天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
163 2
|
20天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1576 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
22天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
977 14
|
4天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
221 2
|
17天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
734 9