Java 网络原理 ①-IO多路复用 || 自定义协议 || XML || JSON

这里是Themberfue

在学习完简单的网络编程后,我们将更加深入网络的学习——HTTP协议、TCP协议、UDP协议、IP协议........... 


IO多路复用 

        ✨在上一节基于 TCP 协议 编写应用层代码时,我们通过一个线程处理连接的申请,随后通过多线程或者线程池来处理对每个客户端的请求;这样,一个客户端就对应一个线程。

        但随着客户端的数量不断增加,反复的创建和销毁线程,其开销都是很大的,哪怕是通过线程池处理,开销也是不容小觑的。

        ✨所以,为了解决这一问题,IO多路复用便诞生了:传统的IO操作是 阻塞式 的,当程序等待一个IO操作时,其他的IO操作会挂起,而 IO多路复用 允许程序同时监视多个 IO通道,从而不用为每个IO通道都单独地创建线程或进程。

        简单来说,就是一个线程就可以同时处理多个客户端的请求

        ✨举个例子:在大学生活中,给室友带饭是非常常见的的现象,假如你现在给两个室友带饭(总共买三份,你自己也得吃啊),你就要出去买三份晚餐,假设这三份晚餐都是在不一样的小吃摊贩卖的。

        这里的视角是,你是服务端,小吃摊老板是客户端,小吃摊老板做完后给你相当于给你发送请求,代入这个视角更好理解~~~

        第一种购买方案:你到了小吃摊A跟老板A说要一份晚餐,你等待老板A做完后,立刻去小吃摊B跟老板B说要一份晚餐,你等待老板B做完后,立刻去小吃摊C跟老板C说要一份晚餐,你等待老板C做完后;OK,此时全部请求处理完了。这里就相当于是单个线程处理完一个请求后立马处理下一个请求。

        第二种购买方案:你叫上其他两个认识的人(这里以甲乙丙代称),和你一起去买,到小吃摊A小吃摊A跟老板A说要一份晚餐,到小吃摊B跟老板B说要一份晚餐,到小吃摊C跟老板C说要一份晚餐;等到三份晚餐都做完后,全部请求也就处理完了。这里就相当于是创建了多个线程同时处理多个请求。

        第三种购买方案:依旧是你一个人买三份晚餐,但与第一种方案不同的是,你到了小吃摊A跟老板A说要一份晚餐,此时你立刻去小吃摊B跟老板B说要一份晚餐,随后又去吃摊C跟老板C说要一份晚餐;然后你就开始等他们做了,小吃摊A老板A做完后,你去拿,小吃摊B老板B做完后,你去拿,小吃摊C老板C做完后,你去拿;拿完全部之后,全部请求也就处理完了。这里就只用了一个线程就同时处理了多个请求。这便是 IO多路复用 的形象比喻

        ✨一般来说,绝大部分客户端,大部分时间都是沉默的,虽然连接了,但不会一直发送请求,此时工作线程等待就行了,等到客户端发来请求后,工作线程处理就OK了;很小的概率会说多个客户端同时发送请求的,这时候就灵活切换到线程池就可以了~~~

        ✨目前,IO多路复用 是服务器开发中主流的核心技术;不过这并不需要程序员自己实现,这是操作系统内置的,只需要调用API即可Java通过 NIO 封装了 IO多路复用


❤️以下是GPT-4o对 IO多路复用 的简单讲解:

IO 多路复用(I/O Multiplexing)

IO 多路复用是一种高效管理多个 IO 通信通道的技术,常用于需要同时处理多个网络连接或文件描述符的场景,比如高并发服务器的设计。它通过一种机制,让程序可以同时监听多个 IO 事件(如读、写、错误),并根据事件的发生进行相应处理。


1. 什么是 IO 多路复用?

传统的 IO 操作是 阻塞式 的,当程序等待一个 IO 操作完成时,其他的 IO 操作会被挂起。IO 多路复用允许程序同时监视多个 IO 通道,而不用为每个通道都创建独立的线程或进程。


2. 核心思想

IO 多路复用通过一个单独的线程或进程,利用系统调用 轮询事件通知 的方式,等待多个文件描述符上发生的事件,并在事件发生时通知应用程序处理。


3. 常见的 IO 多路复用机制

  1. select

    • 原理
      通过将一组文件描述符放入一个集合中,交给内核监听。内核阻塞直到其中一个文件描述符准备就绪。
    • 特点
      • 跨平台支持好。
      • 文件描述符数量有限制(通常是 1024)。
    • 缺点
      • 每次调用都需要重新设置监听集合。
      • 随着文件描述符增多,性能下降。
  2. poll

    • 原理
      类似于 select,但用链表代替固定大小的集合。
    • 特点
      • 无文件描述符数量限制。
      • 支持更大规模的并发连接。
    • 缺点
      • 仍需轮询文件描述符,性能会随描述符增多而下降。
  3. epoll

    • 原理
      提供事件驱动机制,支持 边缘触发水平触发 模式。
    • 特点
      • 只需注册一次文件描述符,后续只需监听。
      • 高效,适合高并发场景。
    • 优点
      • 内核维护了一个事件表,避免了重复传递描述符集合。
      • 边缘触发模式减少了无效通知。

4. IO 多路复用与传统模型的比较

模型描述优缺点
阻塞 IO程序阻塞直到 IO 完成。简单直观,但效率低。
非阻塞 IO程序不断轮询 IO 状态,直到操作完成。CPU 开销大,适用于短时间 IO 操作。
IO 多路复用一个线程监控多个文件描述符的 IO 状态,统一处理就绪事件。高效,适用于大量连接但 IO 操作较少的场景。
多线程/多进程 IO为每个连接创建线程/进程进行 IO 操作。简化编程模型,但线程/进程开销大,不适合高并发。
异步 IO操作提交后立即返回,由操作系统完成 IO,并通知程序。高效,但实现复杂,且操作系统支持有限。

5. IO 多路复用的应用场景

  1. 高并发网络服务器

    • 需要同时处理大量的客户端连接。
    • 示例:Web 服务器、聊天室、负载均衡器。
  2. 实时通信

    • 实时监控多个 IO 通道,快速响应。
    • 示例:即时聊天、视频直播。
  3. 文件监控和操作

    • 需要监听多个文件或套接字的状态。
    • 示例:日志实时监控工具。

6. IO 多路复用的优缺点

优点
  • 单线程即可管理多个 IO,减少线程上下文切换。
  • 提高了系统的吞吐能力,适合高并发场景。
  • 灵活,可根据不同的 IO 状态做不同处理。
缺点
  • 编程复杂度较高。
  • selectpoll 的性能在高连接数时会显著下降。
  • 对某些事件处理可能需要特殊优化。

7. epoll 的工作模式

  • 水平触发(LT, Level Triggered)
    文件描述符有事件发生时会不断通知应用程序,直到事件被处理完毕。
    特点:简单可靠,但可能导致重复通知。

  • 边缘触发(ET, Edge Triggered)
    文件描述符只有在事件发生的那一刻通知一次,之后不会重复通知。
    特点:高效,但要求应用程序及时处理数据。


总结

IO 多路复用是现代高并发服务器的基础,能够高效管理多个 IO 通道。在实际开发中,根据场景选择合适的多路复用机制(如 selectpollepoll),并结合具体业务需求和性能要求进行优化设计。


自定义协议 

        ✨作为程序员的我们一般都是工作在应用层的,应用层所涉及到的许多的网络通信协议大多都是程序员自己自定义的;这里的自定义的并不是说单独写一个新的协议,类似于 TCP、UDP、IP协议这种,当然了,我们也大概率没有那个能力。

        ✨这里的自定义协议通常规定客户端在请求时发送给服务器的特定数据,然后服务端根据这些数据进行解析,随后返回响应给客户端。

        ✨自定义协议通常指在网络通信中,为特定应用设计的一套规则,用于定义通信双方如何组织、传输和解释数据。通常情况下,程序员需要根据实际需求在应用层设计自定义协议,确保不同系统或设备之间能够正确通信。


如何自定义协议

        第一:需要明确需求,根据业务场景和逻辑进行自定义规则的编写,确定传输哪些数据。

        ✨第二:约定好数据的组织格式。

        ✨我们以点外卖为例子进行说明,进行点外卖前,我们肯定得先选择哪个店家,所以软件会显示出数家外卖店家;在显示出外卖店家前,还有一个步骤是用户看不到,那就是在点击进入店家浏览页面时,你作为客户端会立即向该软件的服务器发送一个请求;但不能单单地发送请求,这里就需要明确客户端发送哪些数据。

        比如:请求应该发送 客户的id、客户的位置、客户的经纬度、客户的偏好......,有了这些数据,服务器就会根据这些数据进行解析。

        服务器解析完后,就会给客户端返回一个响应,响应的数据可能包括:商家id、商家名称、商家图片、商家评分、商家热门商品、配送费用......

        在传输数据之前,如果没有一个约定好的格式对这些数据进行组织,这些数据就会乱套,导致数据解析发送错误,这便是第二步的 约定好数据的组织格式 的重要性。


组织数据的格式

纯文本

        数据以简单的字符串形式存储,每行或每部分以分隔符(如逗号、空格、换行符)区分。

# 请求数据
114514,江西省赣州市....,24N115E,螺狮粉\n# 响应数据
1,商家名称1,商家图片1,商家评分1,商家热门商品1,配送费用\n
2,商家名称2,商家图片2,商家评分2,商家热门商品2,配送费用\n
3,商家名称3,商家图片3,商家评分3,商家热门商品3,配送费用\n
4,商家名称4,商家图片4,商家评分4,商家热门商品4,配送费用\n

        类似于上面的组织格式,以 ',' 来规定数据列之间的间隔,以' \n' 来规定数据行之间的间隔;当然,这里的格式纯属由程序员喜好自定义,这便是自定义的一步。

  • 优点

    1. 简单易懂,几乎不需要学习成本。
    2. 易于使用文本编辑器查看和修改。
    3. 对小型文件非常友好。
  • 缺点

    1. 缺乏结构化信息,难以表示复杂数据。
    2. 易出错,无法验证数据有效性。
    3. 没有标准化支持。
  • 适用场景:简单的日志记录、小型配置文件。


✨XML

        (eXtensible Markup Language)一种标记语言,使用标签组织层级化数据;类似于 HTML,但 HTML 的标签是规定好的,而 XML 则可以由程序员自定义。

<!-- 请求 -->
<request><userId>114514</userId><userPosition>江西省赣州市</userPosition><transit>24N115E</transit><favor>螺狮粉</favor>
</request><!-- 响应 -->
<response><shop><id>1</id><nickName>商家名称1</nickName><image>商家图片1</image><rank>商家评分1</rank><hotGoods>商家热门商品1</hotGoods><sendPrice>配送费用</sendPrice></shop>
</response>
  • 优点
    1. 可读性强
    2. 表示层次结构和复杂关系非常直观。
    3. 可扩展性强,可以自定义标签。
    4. 配备丰富的验证工具(如 DTD、XSD)。
  • 缺点
    1. 数据量大,冗余较多,影响传输效率。
    2. 人工编辑不直观,容易出错。
    3. 性能比 JSON 和二进制格式差。
    4. 传输带宽消耗大
  • 适用场景:早期的 Web 服务(SOAP)、配置文件、文档管理。

✨JSON

        JavaScript Object Notation)一种轻量级的数据交换格式,基于键值对。

{userId:114514,userPosition:江西省赣州市,transit:24N115E,favor:螺狮粉
}
  • 优点

    1. 简单易读,结构直观。
    2. 数据量较小,相比 XML 更适合网络传输。
    3. 被广泛支持,大多数语言都内置 JSON 解析库。
    4. 支持数组,易表示复杂数据结构。
  • 缺点

    1. 不支持注释,调试配置文件时不够灵活。
    2. 无内置数据类型定义(如数字的范围、枚举值等)。
    3. 在数据量特别大时,解析性能仍逊于二进制格式。
  • 适用场景:RESTful API、前后端数据交换、轻量级配置文件。


✨Protobuf

        (Protocol Buffers)Google 开发的一种高效的二进制序列化格式。

// 数据结构定义文件 .proto
message User {int32 id = 1;string position = "江西省赣州市";string transit = "24N115E";string favor = "螺狮粉";
}// 对应的二进制序列化数据:
0A 05 41 6C 69 63 65 10 1E 1A 08 4E 65 77 20 59 6F 72 6B
  • 优点
    1. 序列化后数据体积小,性能高。
    2. 使用 .proto 文件强类型定义数据结构,防止数据错误。
    3. 向后兼容性好,可升级字段。
  • 缺点
    1. 可读性差,不适合直接查看和调试。
    2. 初学者需要学习其数据定义和生成工具的使用。
  • 适用场景:高性能分布式系统、大规模数据传输(如微服务之间通信)。

✨对比总结
特性纯文本XMLJSONProtobuf
可读性很高中等很低
结构化支持很强很强
效率(传输/解析)较低较低较高很高
文件体积较小很大较小很小
兼容性中等很高
使用场景简单场景配置和层次数据API 和交换数据高性能传输

选择数据格式的建议

  1. 小型项目或临时数据:使用纯文本或 JSON。
  2. 复杂结构的配置文件:可以使用 JSON 或 XML。
  3. 高性能需求或大规模系统:优先选择 Protobuf。
  4. 需要易读性和广泛兼容性:选择 JSON。
  5. 层次结构复杂且需要强校验:选择 XML。

不同场景选择合适的格式,能够显著提高项目的可维护性和效率。

 下节我们将进入著名的应用层协议——HTTP/HTTPS协议的讲解~~~

毕竟不知后事如何,且听下回分解 

❤️❤️❤️❤️❤️❤️❤️

 

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

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

相关文章

考研互学互助系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库…

SpringBoot使用外置的Servlet容器(详细步骤)

嵌入式Servlet容器&#xff1a;应用打成可执行的jar 优点&#xff1a;简单、便携&#xff1b; 缺点&#xff1a;默认不支持JSP、优化定制比较复杂.&#xff1b; 外置的Servlet容器&#xff1a;外面安装Tomcat---应用war包的方式打包&#xff1b; 操作步骤&#xff1a; 方式一&…

Unity中的LayoutGroup与LayoutElement的实战应用

在开发中遇到过一个问题&#xff0c;首先我们是在4k分辨率下开发的&#xff0c;界面要求如下 我们以第二行为例子&#xff0c;第二行有3个界面&#xff0c;其中中间的界面是比较长的 面板中使用Vertical和Horizontal排列&#xff0c;并且勾选了ControlChildSize和ChildForceEx…

反应力场的生成物、反应路径分析方法

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

“自动驾驶第一股” 图森未来退市转型:改名 CreateAI、发布图生视频大模型 “Ruyi”

12 月 19 日&#xff0c;自动驾驶公司图森未来&#xff08;TuSimple&#xff09;宣布启用全新品牌 CreateAI&#xff0c;并发布多项在生成式 AI 领域的进展。 CreateAI 宣布获著名武侠 IP《金庸群侠传》正版授权&#xff0c;将开发一款大型武侠开放世界 RPG 游戏。 新的 Creat…

FreeRTOS实战——一、基于HAL库项目的FreeRTOS移植步骤

FreeRTOS实战——一、基于HAL库项目的移植步骤 文章目录 FreeRTOS实战——一、基于HAL库项目的移植步骤前言一、下载和移植FreeRTOS二、系统文件配置2.1 FreeRTOSConfig.h中添加如下3个配置&#xff1a;2.2 修改stm32f1xx_it.c 前言 废话不多说&#xff0c;在FreeRTOS基础&…

编程初学者使用 MariaDB 数据库反射生成

编程初学者使用 MariaDB 数据库反射生成 数据库反射生成&#xff0c;是动词算子式通用代码生成器提供的高级功能&#xff0c;可以利用已有的数据库&#xff0c;反射生成相应数据库的前端和后端项目。此功能自动化程度很高&#xff0c;并且支持完善的元数据和数据编辑&#xff…

yolov6算法及其改进

yolov6算法及其改进 1、YOLOV6简介2、RepVGG重参思想3、YOLOv6架构改进3.1、Backbone方面3.2、SPP改进3.3、Neck改进3.4、Head改进 4、正负样本匹配与损失函数4.1、TaskAligned样本匹配4.2、VFL Loss分类损失函数4.3、SIOU损失函数4.4、DFL损失函数 1、YOLOV6简介 YOLOv6设计主…

面试241228

面试可参考 1、cas的概念 2、AQS的概念 3、redis的数据结构 使用场景 不熟 4、redis list 扩容流程 5、dubbo 怎么进行服务注册和调用&#xff0c;6、dubbo 预热 7如何解决cos上传的安全问题kafka的高并发高吞吐的原因ES倒排索引的原理 spring的 bean的 二级缓存和三级缓存 spr…

小程序配置文件 —— 13 全局配置 - window配置

全局配置 - window配置 这里讲解根目录 app.json 中的 window 字段&#xff0c;window 字段用于设置小程序的状态栏、导航条、标题、窗口背景色&#xff1b; 状态栏&#xff1a;顶部位置&#xff0c;有网络信号、时间信息、电池信息等&#xff1b;导航条&#xff1a;有一个当…

STM32 与 AS608 指纹模块的调试与应用

前言 在嵌入式系统中&#xff0c;指纹识别作为一种生物识别技术&#xff0c;广泛应用于门禁系统、考勤机、智能锁等场景。本文将分享如何在 STM32F103C8T6 开发板上使用 AS608 指纹模块&#xff0c;实现指纹的录入和识别功能。 硬件准备 STM32F103C8T6 开发板AS608 指纹模块…

3GPP R18 MT-SDT

Rel-17 指定MO-SDT允许针对UL方向的数据包进行小数据包传输。对于DL,MT-SDT(即DL触发的小数据)可带来类似的好处,即 通过不转换到 RRC_CONNECTED来减少信令开销和UE功耗,并通过允许快速传输(小而少见的)数据包(例如用于定位)来减少延迟。 在R17中,NR_SmallData_INACTIVE的工…

小程序基础 —— 02 微信小程序账号注册

微信小程序账号注册 小程序开发与网页开发不一样&#xff0c;在开始微信小程序开发之前&#xff0c;需要访问微信公众平台&#xff0c;注册一个微信小程序账号。 有了小程序的账号以后&#xff0c;才可以开发和管理小程序&#xff0c;后续需要通过该账号进行开发信息的设置、…

两个链表的第一个公共结点

输入两个链表&#xff0c;找出它们的第一个公共结点。 当不存在公共节点时&#xff0c;返回空节点。 数据范围 链表长度 [1,2000] 保证两个链表不完全相同&#xff0c;即两链表的头结点不相同。 算法思想描述 如上图所示&#xff0c;两种链表的出现的情况只有图中2中&…

OpenAI 12天发布会:AI革命的里程碑@附35页PDF文件下载

在人工智能的浪潮中&#xff0c;OpenAI的12天发布会无疑是2024年科技界的一场盛宴。从12月5日开始&#xff0c;OpenAI连续12天每天发布一个新应用或功能&#xff0c;标志着AI技术的又一次飞跃。本文将梳理这些激动人心的发布&#xff0c;带你一探究竟。 OpenAI发布会概览 Ope…

理解数列和函数的极限

什么是数列 数列就是按照1定顺序排列的数字&#xff0c; 也可以理解为包含数字元素的队列 格式: a 1 , a 2 , a 3 , . . . , a n a_1, a_2, a_3, ..., a_n a1​,a2​,a3​,...,an​, n ∈ N n \in N n∈N 或者 { a n } \{ a_n \} {an​}, n ∈ N n \in N n∈N 其中 a n…

TOP K问题:利用堆排序找出数组中最小的k个数

设计一个算法&#xff0c;找出数组中最小的k个数。以任意顺序返回这k个数均可。 找小的数需要建大堆来解决&#xff0c;首先将数组中前K个数建成一个大堆&#xff0c;将从k1个数直到数组结束的所有数与堆顶的数进行比较&#xff0c;如果比堆顶的数小&#xff0c;则替换堆顶的数…

6-Gin 路由详解 --[Gin 框架入门精讲与实战案例]

Gin 是一个用 Go 语言编写的 HTTP Web 框架&#xff0c;以其高性能和简洁的 API 而闻名。它提供了一套强大的路由功能&#xff0c;使得开发者可以轻松地定义 URL 路由规则&#xff0c;并将这些规则映射到具体的处理函数&#xff08;handler&#xff09;。以下是关于 Gin 路由的…

【数据库初阶】Linux中库的基础操作

&#x1f389;博主首页&#xff1a; 有趣的中国人 &#x1f389;专栏首页&#xff1a; 数据库初阶 &#x1f389;其它专栏&#xff1a; C初阶 | C进阶 | 初阶数据结构 亲爱的小伙伴们&#xff0c;大家好&#xff01;在这篇文章中&#xff0c;我们将深入浅出地为大家讲解 Linux…

【机器学习(九)】分类和回归任务-多层感知机(Multilayer Perceptron,MLP)算法-Sentosa_DSML社区版 (1)11

文章目录 一、算法概念11二、算法原理&#xff08;一&#xff09;感知机&#xff08;二&#xff09;多层感知机1、隐藏层2、激活函数sigma函数tanh函数ReLU函数 3、反向传播算法 三、算法优缺点&#xff08;一&#xff09;优点&#xff08;二&#xff09;缺点 四、MLP分类任务实…