Servlet(一)

一.什么是servlet

Servlet 是一种实现动态页面的技术。 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app。

1.回顾 动态页面 vs 静态页面

静态页面也就是内容始终固定的页面。即使 用户不同/时间不同/输入的参数不同 , 页面内容也不会发生变化。(除非网站的开发人员修改源代码, 否则页面内容始终不变)。对应的, 动态页面指的就是 用户不同/时间不同/输入的参数不同, 页面内容会发生变化。
在这里插入图片描述
举个例子哔哩哔哩由于用户输入的参数或者时间不同页面是会发生变化的,所以它是一个动态页面。
构建动态页面的技术有很多, 每种语言都有一些相关的库/框架来做这件事。
Servlet 就是 Tomcat 这个 HTTP 服务器提供给 Java 的一组 API, 来完成构建动态页面这个任务。

2.servlet 主要做的工作

允许程序猿注册一个类, 在 Tomcat 收到某个特定的 HTTP 请求的时候, 执行这个类中的一些代码。
帮助程序猿解析 HTTP 请求, 把 HTTP 请求从一个字符串解析成HttpRequest 对象。
帮助程序猿构造 HTTP 响应. 程序猿只要给指定的 HttpResponse 对象填写一些属性字段, Servlet就会自动的安装 HTTP 协议的方式构造出一个 HTTP 响应字符串, 并通过 Socket 写回给客户端。

简而言之, Servlet 是一组 Tomcat 提供的 API, 让程序猿自己写的代码能很好的和 Tomcat 配合起来, 从而更简单的实现一个 web app。而不必关注 Socket, HTTP协议格式, 多线程并发等技术细节, 降低了 web app 的开发门槛, 提高了开发效率。

二.第一个 Servlet 程序

1. 创建项目

使用 IDEA 创建一个 Maven 项目。

  1. 菜单 -> 文件 -> 新建项目 -> Maven
    在这里插入图片描述
    一定要选择Maven!!! Maven是java中常用的构建工具,一个程序在编写过程中,往往需要涉及第三方库的依赖,另外还需要针对这个写好的程序进行打包****部署 Maven存在的意义就是能够方便的对依赖进行管理和打包。
    打开后看编译器左边:
    在这里插入图片描述

2. 引入依赖

当前的代码要使用servlet开发,servlet并不是java标准库自带的,而是Tomcat提供的api,所以得先把servlet的依赖获取过来。

  1. 在中央仓库中央仓库地址中搜索 “servlet”, 找到java servlet api
    在这里插入图片描述

点开java servlet api
在这里插入图片描述
选择3.1.0版本。Servlet和Tomcat是对应关系,如果Tomcat版本是8,那么Servlet版本是3.1,如果不匹配可能出现问题。
在这里插入图片描述
复制这段代码到pom文件

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope>
</dependency>

先写标签,然后标签里面把复制的代码写入。
在这里插入图片描述
在这里插入图片描述
点击Maven
在这里插入图片描述
点击该按钮刷新Maven,一般引入的依赖都得手动刷新
在这里插入图片描述
如果控制台出现这种情况说明你的环境没有配对
在这里插入图片描述
解决这个问题首先File->settings->Maven
在这里插入图片描述
点击Maven home path:
在这里插入图片描述
然后选择这个文件
在这里插入图片描述

同理选择usering settings file:
在这里插入图片描述
选择该文件然后点击刷新再看控制台,此时就没有报错了。
在这里插入图片描述

3. 创建目录

Tomcat对于Servlet项目是有一定的额外要求的,Maven是一个通用的工具,可以管理的不仅仅是Servlet项目,还可以管理其他项目,在这个基础上,在按照Servlet项目要求创建出一些特定的目录和文件。
在这里插入图片描述
web.xml文件的代码是固定的,编译器报红是正常的!!!
在这里插入图片描述

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name></web-app>

4. 编写代码

在 java 目录中创建一个类 HelloServlet, 代码如下:
在这里插入图片描述
创建一个类 HelloServlet , 继承自 HttpServlet,如果HttpServlet类编译器报红说明Servlet的依赖没有正确的引入,如果颜色正常说明引入成功。
在这里插入图片描述
req代表的是这次HTTP请求的内容,resp代表响应的内容。doGet是重写父类的方法,该方法本身是HttpServlet的。doGet方法不需要手动调用,本质是一个回调函数,把这个方法写好后会交给Tomcat,Tomcat在收到一个合适的请求后就会调用doGet方法。调用doGet的时候,Tomcat就会解析这次的HTTP请求,生成一个HttpservletRequest对象(这个对象的属性啥的都是HTTP协议格式),同时Tomcat也会构造出一个空的HttpServletRequese对象,把这个对象传到doGet里面,doGet要做的事情就是根据请求计算响应。doGet里面的代码就会根据req里面的不同参数的细节,生成一个具体的resp对象(往空对象里面设计属性),tomcat就会根据这个响应对象转换符号http协议的响应报文返回给浏览器。

创建一个类 HelloServlet , 继承自 HttpServlet,在这个类上方加上 @WebServlet(“/hello”) 注解, 表示 Tomcat 收到的请求中, 路径为 /hello的请求才会调用 HelloServlet 这个类的代码.。(这个路径未包含 Context Path),重写 doGet 方法,doGet 的参数有两个, 分别表示收到的 HTTP 请求 和要构造的 HTTP 响应.。这个方法会在 Tomcat 收到 GET 请求时触发HttpServletRequest 表示 HTTP 请求。Tomcat 按照 HTTP 请求的格式把 字符串 格式的请求转成了一个 HttpServletRequest 对象。后续想获取请求中的信息(方法, url, header, body 等) 都是通过这个对象来获取。HttpServletResponse 表示 HTTP 响应。代码中把响应对象构造好(构造响应的状态码, header,body 等)。resp.getWriter() 会获取到一个流对象, 通过这个流对象就可以写入一些数据, 写入的数据会被构造成一个 HTTP 响应的 body 部分, Tomcat 会把整个响应转成字符串, 通过 socket 写回给浏览器。

这个代码虽然只有寥寥几行, 但是包含的信息量是巨大的。

  1. 我们的代码不是通过 main 方法作为入口了。main 方法已经被包含在 Tomcat 里, 我们写的代码会被 Tomcat 在合适的时机调用起来。
    此时我们写的代码并不是一个完整的程序, 而是 Tomcat 这个程序的一小部分逻辑。
  2. 我们随便写个类都能被 Tomcat 调用嘛? 满足啥样条件才能被调用呢?
    主要满足三个条件:
    a) 创建的类需要继承自 HttpServlet
    b) 这个类需要使用 @WebServlet 注解关联上一个 HTTP 的路径
    c) 这个类需要实现 doXXX 方法。
    当这三个条件都满足之后, Tomcat 就可以找到这个类, 并且在合适的时机进行调用。

5. 打包程序

使用 maven 进行打包. 打开 maven 窗口 (一般在 IDEA 右侧就可以看到 Maven 窗口, 如果看不到的话,可以通过 菜单 -> View -> Tool Window -> Maven 打开),然后展开 Lifecycle , 双击 package 即可进行打包.
在打包之前pom文件中加这段代码
在这里插入图片描述

 <packaging>war</packaging><build><finalName>java108</finalName></build>

这段代码的意思是打出来的包叫什么名字,finalname标签中写的是java108,所以包打出来的名字是java108。Tomact需要的是war包,并非jar包,所以往pom文件中写入war标签把jar包改为war包。

war 包和 jar 包的区别
jar 包是普通的 java 程序打包的结果. 里面会包含一些 .class 文件。
war 包是 java web 的程序, 里面除了会包含 .class 文件之外, 还会包含 HTML, CSS, JavaScript, 图
片, 以及其他的 jar 包。打成 war 包格式才能被 Tomcat 识别.

在这里插入图片描述
如果比较顺利的话, 能够看到 SUCCESS 这样的字样.
在这里插入图片描述
打包成功后, 可以看到在 target 目录下, 生成了一个 war 包.
在这里插入图片描述

然后打开这个war包的路径
在这里插入图片描述
点击Explorer在文件夹中找到打出来的包
在这里插入图片描述
把 war 包拷贝到 Tomcat 的 webapps 目录下。
在这里插入图片描述
当复制进来后Tomcat就能识别有新的webapp来了,对新的war包进行压缩。
## 7. 验证程序
此时通过浏览器访问 http://127.0.0.1:8080/java108/hello1就能看到结果了
在这里插入图片描述
在这里插入图片描述

8.更方便的部署方式

手动拷贝 war 包到 Tomcat 的过程比较麻烦. 我们还有更方便的办法。此处我们使用 IDEA 中的 Smart Tomcat 插件完成这个工作。

理解 “插件” (plugin)

在这里插入图片描述

天火 + 擎天柱 => 会飞的擎天柱。
天火在牺牲之前把自己变成了擎天柱的 “飞行插件”。在擎天柱需要起飞的时候就变成翅膀装在擎天柱身上。不需要起飞的时候就卸下来放到擎天柱的集装箱里。程序开发的时候也经常如此。像 IDEA 这样的程序虽然功能强大, 但是也无法面面俱到。对于一些特殊场景的功能, 开发者就可以开发一些 “插件”。如果需要这个插件, 就单独安装。插件就是对程序的一些特定场景, 做出一些特定的功能的扩展。

9.安装 Smart Tomcat 插件

  1. 菜单 -> 文件 -> Settings
    在这里插入图片描述
  2. 选择 Plugins, 选择 Marketplace, 搜索 “tomcat”, 点击 “Install”.
    在这里插入图片描述
  3. 安装完毕之后, 会提示 “重启 IDEA”

配置 Smart Tomcat 插件

  1. 点击右上角的 “Add Configuration”
    在这里插入图片描述
  2. 选择左侧的 “Smart Tomcat”
    在这里插入图片描述
  3. 在 Name 这一栏填写一个名字(可以随便写)在 Tomcat Server 这一栏选择 Tomcat 所在的目录. 其他的选项不必做出修改。
  4. 点击 OK 之后, 右上角变成了
    在这里插入图片描述

点击run:
在这里插入图片描述
然后浏览器输入url查看结果。
在这里插入图片描述
使用 Smart Tomcat 部署的时候, 我们发现 Tomcat 的 webapps 内部并没有被拷贝一个 war 包,
也没有看到解压缩的内容。Smart Tomcat 相当于是在 Tomcat 启动的时候直接引用了项目中的 webapp 和 target 目录。

三.几种常见的错误

1.出现 404

在这里插入图片描述
404 表示用户访问的资源不存在。大概率是 URL 的路径写的不正确。
错误实例2: 少写了 Servlet Path通过 /eat1访问服务器。
错误实例3: Servlet Path 写的和 URL 不匹配。
错误实例4: web.xml 写错了
清除 web.xml 中的内容
在这里插入图片描述

在 Tomcat 启动的时候也有相关的错误提示
在这里插入图片描述

2.出现 405

405 表示对应的 HTTP 请求方法没有实现.
错误实例: 没有实现 doGet 方法.

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
}

在这里插入图片描述

在浏览器地址栏直接输入 URL , 会发送一个 HTTP GET 请求。此时就会根据 /eat1/hello1 这个路径找到 HelloServlet 这个类. 并且尝试调用HelloServlet 的 doGet 方法。但是如果没有实现 doGet 方法, 就会出现上述现象。

3.出现 500

往往是 Servlet 代码中抛出异常导致的。
错误实例:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {String s = null;resp.getWriter().write(s.length());}}

重启 Tomcat 服务器。重新访问页面, 可以看到:
在这里插入图片描述
异常信息里已经提示了出现异常的代码是 HelloServlet.java 的第 13 。resp.getWriter().write(s.length());仔细检查这里的代码就可以看到空指针异常。

4.出现 “空白页面”

错误实例:
修改代码, 去掉 resp.getWritter().write() 操作。

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {System.out.println("hello");}}

重启服务器,访问服务器, 可以看到一个空白页面。
抓包可以看到, 响应 body 中的内容就是 “空数据”
在这里插入图片描述

5.小结

初学 Servlet, 遇到的这类问题会非常多。我们不光要学习 Servlet 代码的基本写法, 也要学习排查错误的思路。程序猿调试 BUG 如同医生诊病。
一个有经验的程序猿和一个新手程序猿相比, 最大的优势往往不是代码写的多好, 而是调试效率有多高.。同一个问题可能新手花了几天都无法解决的, 但是有经验的程序猿可能几分钟就搞定了。
你还觉得 “程序猿是吃青春饭” 嘛?熟悉 HTTP 协议能够让我们调试问题事半功倍。4xx 的状态码表示路径不存在, 往往需要检查 URL 是否正确, 和代码中设定的 Context Path 以及Servlet Path 是否一致。
5xx 的状态码表示服务器出现错误, 往往需要观察页面提示的内容和 Tomcat 自身的日志, 观察是否
存在报错。
出现连接失败往往意味着 Tomcat 没有正确启动, 也需要观察 Tomcat 的自身日志是否有错误提示。
空白页面这种情况则需要我们使用抓包工具来分析 HTTP 请求响应的具体交互过程。

Servlet 运行原理

在 Servlet 的代码中我们并没有写 main 方法, 那么对应的 doGet 代码是如何被调用的呢? 响应又是如何返回给浏览器的?

Tomcat 的定位

我们自己的实现是在 Tomcat 基础上运行的。
在这里插入图片描述

当浏览器给服务器发送请求的时候, Tomcat 作为 HTTP 服务器, 就可以接收到这个请求。HTTP 协议作为一个应用层协议, 需要底层协议栈来支持工作. 如下图所示:
在这里插入图片描述
更详细的交互过程可以参考下图:
在这里插入图片描述

  1. 接收请求:
    用户在浏览器输入一个 URL, 此时浏览器就会构造一个 HTTP 请求。
    这个 HTTP 请求会经过网络协议栈逐层进行 封装 成二进制的 bit 流, 最终通过物理层的硬件设备转换成光信号/电信号传输出去。
    这些承载信息的光信号/电信号通过互联网上的一系列网络设备, 最终到达目标主机(这个过程也需要网络层和数据链路层参与)。
    服务器主机收到这些光信号/电信号, 又会通过网络协议栈逐层进行 分用, 层层解析, 最终还原成HTTP 请求. 并交给 Tomcat 进程进行处理(根据端口号确定进程)
    Tomcat 通过 Socket 读取到这个请求(一个字符串), 并按照 HTTP 请求的格式来解析这个请求, 根据请求中的 Context Path 确定一个 webapp, 再通过 Servlet Path 确定一个具体的 类.。再根据当前请求的方法 (GET/POST/…), 决定调用这个类的 doGet 或者 doPost 等方法。 此时我们的代码中的doGet / doPost 方法的第一个参数 HttpServletRequest 就包含了这个 HTTP 请求的详细信息。
  1. 根据请求计算响应:

在我们的 doGet / doPost 方法中, 就执行到了我们自己的代码. 我们自己的代码会根据请求中的一
些信息, 来给 HttpServletResponse 对象设置一些属性. 例如状态码, header, body 等。

  1. 返回响应:

我们的 doGet / doPost 执行完毕后, Tomcat 就会自动把 HttpServletResponse 这个我们刚设置好的对象转换成一个符合 HTTP 协议的字符串, 通过 Socket 把这个响应发送出去。此时响应数据在服务器的主机上通过网络协议栈层层 封装, 最终又得到一个二进制的 bit 流, 通过物理层硬件设备转换成光信号/电信号传输出去。
这些承载信息的光信号/电信号通过互联网上的一系列网络设备, 最终到达浏览器所在的主机(这个过程也需要网络层和数据链路层参与)。
浏览器主机收到这些光信号/电信号, 又会通过网络协议栈逐层进行 分用, 层层解析, 最终还原成HTTP 响应, 并交给浏览器处理。
浏览器也通过 Socket 读到这个响应(一个字符串), 按照 HTTP 响应的格式来解析这个响应. 并且把body 中的数据按照一定的格式显示在浏览器的界面上。

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

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

相关文章

从 Microsoft 官网下载 Windows 10

方法一&#xff1a; 打开 Microsoft 官网&#xff1a; 打开开发人员工具&#xff08;按 F12 或右键点击“检查”&#xff09;。 点击“电脑模拟手机”按钮&#xff0c;即下图&#xff1a; 点击后重新加载此网页&#xff0c;即可看到下载选项。

jenkins 用ssh 启动nohup java -jar显示执行成功 但是jar包没有被启动起来 (已解决)

问题描述 使用jenkins自动部署jar包. 打包传到服务后, 停止stop.sh脚本执行成功. 并且 xx.jar 也成功停止. 但是使用jenkins执行start.sh脚本执行成功, 但是服务器上xx.jar并没有启动起来. 启动命令是 nohup java -jar **.jar --spring.cloud.bootstrap.namebootstrap-debug&…

demo_GAN

# 导入PyTorch库&#xff0c;这是一个用于深度学习的开源库 import torch # 导入PyTorch的神经网络模块&#xff08;nn&#xff09;&#xff0c;用于定义神经网络结构 import torch.nn as nn # 导入PyTorch的函数式模块&#xff08;functional&#xff09;&#xff0c;提供了一…

把其他.ui文件拿到我的工程中使用

在Qt工程中使用工程外的ui文件的方式&#xff1a;作为一个类直接使用、包含到自己的类中或继承使用 将ui文件添加到工程中&#xff0c;作为一个类以直接使用 注&#xff1a;这里指使用原本不属于该工程的ui文件第一步&#xff1a;在工程文件.pro中添加UI文件 在.proj文件中添加…

每日一题——第一百一十七题

题目&#xff1a;使用二分查找&#xff0c;查找一个数是否存在于一个升序数组中 #include <stdio.h>int binarySearch(int arr[], int length, int elem);int main() {int arr[] { 2, 3, 4, 5, 6, 7, 8, 9, 10 };int key;int length sizeof(arr) / sizeof(arr[0]);pri…

Palo Alto Networks Expedition 未授权SQL注入漏洞复现(CVE-2024-9465)

0x01 产品介绍&#xff1a; Palo Alto Networks Expedition 是一款强大的工具&#xff0c;帮助用户有效地迁移和优化网络安全策略&#xff0c;提升安全管理的效率和效果。它的自动化功能、策略分析和可视化报告使其在网络安全领域中成为一个重要的解决方案。 0x02 漏洞描述&am…

windows下安装、配置neo4j并服务化启动

第一步&#xff1a;下载Neo4j压缩包 官网下载地址&#xff1a;https://neo4j.com/download-center/ &#xff08;官网下载真的非常慢&#xff0c;而且会自己中断&#xff0c;建议从以下链接下载&#xff09; 百度网盘下载地址&#xff1a;链接&#xff1a;https://pan.baid…

FFMPEG录屏(17)--- 使用 DwmRegisterThumbnail 捕获指定窗口图像数据

使用 DwmRegisterThumbnail 捕获指定窗口图像数据 在 Windows 平台上&#xff0c;捕获指定窗口的图像数据可以通过多种方法实现&#xff0c;其中一种高效的方法是使用 [DwmRegisterThumbnail] 本文将介绍如何使用 [DwmRegisterThumbnail] 捕获窗口图像数据&#xff0c;并提供一…

Mysql中表字段VARCHAR(N)类型及长度的解释

本文将针对MySQL 中 varchar (N)类型字段的存储方式进行解释&#xff0c;主要是对字符和字节的关系的理解。 1. varchar (N) 中的 N varchar (N) 中的 N 表示字符数&#xff0c;而不是字节数。这意味着 N 表示你可以存储多少个字符。 字符数&#xff1a;指的是字符的个数&…

计算机视觉在疲劳检测中的应用

计算机视觉在疲劳检测中的应用 引言 随着科技的飞速发展&#xff0c;计算机视觉技术已经广泛应用于各个领域&#xff0c;其中疲劳检测是近年来备受关注的一个研究方向。疲劳检测旨在通过计算机视觉技术&#xff0c;实时分析个体的面部特征、动作以及生理信号等&#xff0c;判…

周易解读:八卦02,八卦所代表的基本事物

八 卦02 上一节&#xff0c;我是讲完了八卦的卦象的画法的问题。这一节&#xff0c;我来尝试着去讲解八卦所代表的自然事物。 八卦是谁发明的呢&#xff1f;根据《周易说卦传》的说法&#xff0c;八卦是伏羲发明的。伏羲氏仰观天文&#xff0c;俯察地理&#xff0c;从中提取…

项目模块二:日志宏

一、代码展示 二、补充知识 1、LOG(level, format, ...) format 是用于宏识别格式化&#xff0c;类似于 printf("%s", str); 里面的 "%s" ... 不定参&#xff0c;传入宏的参数除了 level, format, 还有不确定个数的参数。 2、红色 \ 由于宏只能写在一…

PyTorch深度学习入门汇总

PyTorch 是由 Facebook 的人工智能研究小组开发的深度学习框架&#xff0c;可以基于PyTorch开发和训练各种深度学习模型。自 2016 年问世以来&#xff0c;PyTorch 因其灵活性和易用性而受到深度学习从业者的极大关注。 汇总目录 基于conda包的环境创建、激活、管理与删除 Pyt…

链上相遇,节点之间的悸动与牵连

公主请阅 1. 返回倒数第 k 个节点1.1 题目说明1.2 题目分析1.3 解法一代码以及解释1.3 解法二代码以及解释 2.相交链表2.1 题目说明示例 1示例 2示例 3 2.2 题目分析2.3 代码部分2.4 代码分析 1. 返回倒数第 k 个节点 题目传送门 1.1 题目说明 题目名称&#xff1a; 面试题 02…

15分钟学 Go 第 10 天:函数参数和返回值

第10天&#xff1a;函数参数和返回值 目标&#xff1a;理解函数如何传递参数 在Go语言中&#xff0c;函数是程序的基本构建块。了解如何传递参数和返回值是编写高效、可复用代码的重要步骤。本文将详细讲解函数参数的类型、传递方式以及如何处理返回值&#xff0c;辅以代码示…

用C++编写一个简单的游戏引擎:从游戏循环到物理与渲染的全面解析

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 构建一个基础的2D游戏引擎是一项富有挑战性但极具学习价值的任务。本文将通过从零开始的方式,逐步讲解如何使用C++开发一个简单的游戏引擎。内容涵盖了游戏引擎的核心架构设计,包括游戏循环、物理引擎和图形渲染…

DP—子数组,子串系列 第一弹 -最大子数组和 -环形子数组的最大和 力扣

你好&#xff0c;欢迎阅读我的文章~ 个人主页&#xff1a;Mike 所属专栏&#xff1a;动态规划 ​ 53. 最大子数组和 最大子数组和 ​ 分析: 使用动态规划解决 状态表示: 1.以某个位置为结尾 2.以某个位置为起点 这里使用以某个位置为结尾&#xff0c;结合题目要求&#…

MySQL8.0主从同步报ERROR 13121错误解决方法

由于平台虚拟机宿主机迁移&#xff0c;导致一套MySQL主从库从节点故障&#xff0c;从节点服务终止&#xff0c;在服务启动后&#xff0c;恢复从节点同步服务&#xff0c;发现了如下报错&#xff1a; mysql> show slave status\G; *************************** 1. row *****…

GDAL+C#实现矢量多边形转栅格

1. 开发环境测试 参考C#配置GDAL环境&#xff0c;确保GDAL能使用&#xff0c;步骤简述如下&#xff1a; 创建.NET Framework 4.7.2的控制台应用 注意&#xff1a; 项目路径中不要有中文&#xff0c;否则可能报错&#xff1a;can not find proj.db 在NuGet中安装GDAL 3.9.1和G…

OSI参考模型详解:初学者指南与实践案例

OSI参考模型详解&#xff1a;初学者指南与实践案例 OSI&#xff08;Open System Interconnect&#xff09;参考模型是一个由国际标准化组织&#xff08;ISO&#xff09;提出的七层网络分层模型&#xff0c;它为全球所有互联计算机系统提供了一个通用的通信框架&#xff0c;解决…