计算机网络中的OSI七层模型
计算机网络中的OSI(Open Systems Interconnection)七层模型
是一种理论框架,用于描述计算机网络中数据通信的过程。OSI模型将计算机网络通信
过程划分为七个层次,每个层次都有其特定的功能和协议。这种分层结构有助于研究和理解计算机网络中的通信原理
。以下是OSI七层模型的各个层次及其主要功能:
应用层
是OSI模型的第七层,也是网络应用程序
和网络协议
之间的接口。应用层主要负责为用户提供各类应用服务,如文件传输、电子邮件、Web浏览等。
表示层
是OSI模型的第六层,主要负责处理在网络中传输的数据的表示方式,如数据加密、解密、压缩、解压缩
等。表示层确保了不同系统之间的数据兼容性
。
会话层
是OSI模型的第五层,主要负责建立、维护和终止应用程序之间的通信会话。会话层提供了数据交换的同步和确认机制。
传输层
是OSI模型的第四层,主要负责在源主机和目标主机之间提供可靠的、端到端的数据传输服务。传输层通过分段、封装和重组数据来实现可靠的数据传输。常见的传输层协议包括TCP(传输控制协议)
和UDP(用户数据报协议)
。
网络层
是OSI模型的第三层,主要负责将数据包从源主机路
由到目标主机。网络层主要负责逻辑寻址、路由选择和分组转发
。常见的网络层协议包括IP(互联网协议)
和ICMP(互联网控制报文协议)
。
数据链路层
是OSI模型的第二层,主要负责将网络层传来的数据包封装成帧(Frame),并在同一局域网内进行传输。数据链路层主要负责物理寻址、数据成帧、错误检测和流量控制。常见的数据链路层协议包括以太网(Ethernet)、令牌环(Token Ring)和无线局域网(Wi-Fi)
等。
物理层
是OSI模型的第一层,主要负责在物理介质上实现比特流的透明传输。物理层主要关注硬件接口、电气特性、光纤、无线传输等方面的问题。
OSI七层模型提供了一个通用的框架,帮助研究和理解计算机网络中的通信原理。实际应用中,我们通常使用TCP/IP四层模型
,它包括了应用层、传输层、网络层和链路层
,与OSI模型有一定的对应关系。
HTML框架的必要性
HTML框架
进行分层设计的主要原因是为了提高代码的可读性、可维护性和可重用性。将HTML框架
分层可以提高整体项目的结构和逻辑,便于开发者更好地理解和修改代码。分层设计具有以下优点:
- 提高可读性:通过将HTML框架划分为不同的层次,可以使代码结构更清晰,有助于开发者快速理解代码的功能。
- 便于维护:分层设计有助于将功能模块化,这样可以方便地修改或替换某个模块,而不会影响其他部分的代码。这有助于提高项目的可维护性。
- 可重用性:将HTML框架分层可以将公共部分提取为可重用的组件,这样可以在不同项目中重复使用这些组件,提高开发效率。
- 适应性:分层设计可以让HTML框架更容易适应不同的设备和屏幕尺寸,提高项目的兼容性。
- 便于协作:在大型项目中,通常会有多个开发者参与。通过分层设计,开发者可以专注于自己的模块,减少代码冲突和沟通成本。
HTML框架的组成
HTML框架包括Application层``middleware层``route层``codec层``transport层
Application层
应用层通常包括与业务逻辑相关的代码,如Web应用程序的控制器(Controller)、视图(View)和模型(Model)。应用层的主要作用是处理用户请求并返回相应的响应。
Middleware层
中间件层是介于应用层和底层框架之间的一层,负责处理一些通用的功能,如身份验证、授权、缓存、日志记录等。中间件层有助于将业务逻辑与通用功能分离,使得应用层更加简洁和易于维护。
Route层
路由层负责处理HTTP请求的URL和HTTP方法(如GET、POST等),将请求分发到相应的控制器和方法。路由层的主要作用是根据URL映射来定位具体的功能代码。
Codec层
编解码层负责处理数据的编码和解码。在Web开发中,编码和解码通常涉及到HTML、CSS、JavaScript等前端技术的处理,以及JSON、XML等数据交换格式的处理。编解码层的主要作用是将数据转换为特定的格式,以便在不同层之间进行传输和处理。
Transport层
传输层负责处理底层的网络通信,如TCP、UDP等协议的使用。在Web开发中,传输层通常涉及到HTTP协议的处理,包括请求和响应的创建、发送和接收。传输层的主要作用是确保数据的可靠传输和在网络中的正确路由。
这些层次在实际应用中可能因框架和场景的不同而有所差异。但是,从您提供的描述来看,它们分别负责处理Web应用程序中的不同功能,共同构成了一个完整的Web开发框架。
HTML框架和服务端客户端之间的通信对比
Application层
应用层设计
应用层设计主要是设置各种接口
,用于路由
使用。
例如在字节后端进阶版中的大项目中的注册接口
。
/douyin/user/register/ - 用户注册接口
新用户注册时提供用户名,密码,昵称即可,用户名需要保证唯一。创建成功后返回用户 id 和权限token.
接口类型
POST
接口定义
go
复制代码
syntax = "proto2";
package douyin.core;
message douyin_user_register_request {
required string username = 1; // 注册用户名,最长32个字符
required string password = 2; // 密码,最长32个字符
}
message douyin_user_register_response {
required int32 status_code = 1; // 状态码,0-成功,其他值-失败
optional string status_msg = 2; // 返回状态描述
required int64 user_id = 3; // 用户id
required string token = 4; // 用户鉴权token
}
go
复制代码
func Register(username, password string) (id int64, token int64, err error) {
if len(username) > 32 {
return 0, 0, errors.New("用户名过长,不可超过32位")
}
if len(password) > 32 {
return 0, 0, errors.New("密码过长,不可超过32位")
}
// 先查布隆过滤器,不存在直接返回错误,降低数据库的压力
if userNameFilter.TestString(username) {
return 0, 0, errors.New("用户名已经存在!")
}
//雪花算法生成token
node, err := snowflake.NewNode(1) //这里的userIdInt64就是 User.Id(主键)
if err != nil {
log.Println("雪花算法生成id错误!")
log.Println(err)
}
token1 := node.Generate().Int64()
tokenStr := strconv.FormatInt(token1, 10)
user := domain.User{}
// 再查缓存
data, err := dao.RedisClient.Get(context.Background(), tokenStr).Result()
if err == redis.Nil {
fmt.Println("token does not exist")
} else if err != nil {
fmt.Println("Error:", err)
} else {
num, err := strconv.ParseInt(data, 10, 64)
if err != nil {
fmt.Println("Error:", err)
return num, 0, err
}
return num, token1, nil
}
//在查数据库
user = domain.User{}
dao.DB.Model(&domain.User{}).Where("name = ?", username).Find(&user)
if user.Id != 0 {
return 0, 0, errors.New("用户已存在")
}
user.Name = username
// 加密存储用户密码
user.Salt = randSalt()
buf := bytes.Buffer{}
buf.WriteString(username)
buf.WriteString(password)
buf.WriteString(user.Salt)
pwd, err1 := bcrypt.GenerateFromPassword(buf.Bytes(), bcrypt.MinCost)
if err1 != nil {
return 0, 0, err
}
user.Pwd = string(pwd)
//存在mysql里边
dao.DB.Model(&domain.User{}).Create(&user)
//再把用户id作为键 用户的所有信息作为值存在其中
//用户信息的缓存是 保存在redis中 一个以id为键 user json为值
jsonuser, err1 := MarshalUser(user)
if err1 != nil {
fmt.Println("err1", err1)
return 0, 0, err1
}
err = dao.RedisClient.Set(context.Background(), strconv.FormatInt(user.Id, 10), jsonuser, 0).Err()
if err != nil {
fmt.Println("err", err)
return 0, 0, err
}
// 布隆过滤器中加入新用户
userIdFilter.AddString(strconv.FormatInt(user.Id, 10))
userNameFilter.AddString(username)
return user.Id, token1, nil
}
本接口注册功能实现:把所有信息存在mysql里边当然redis里边也存在这些信息,当然username也存在了布容过滤器中去,当接收到用户的username的时候我们现在布容过滤器中先查询是否存在如果存在则直接返回err,不存在然后再在redis里边查询,因为redis相比于mysql是更为轻量级的所以我们要先在redis里边进行查,如果查不到再进mysql里边查去,查不到说明没有注册过,可以注册。
命名规范
遵循命名规范原则。
Middleware层中间件
gin框架里的中间件分为全局中间件,局部中间件。那么什么是中间件?中间件是为应用提供通用服务和功能的软件。数据管理、应用服务、消息传递、身份验证和 API 管理通常都要通过中间件。在gin框架里,就是我们的所有API接口都要经过我们的中间件,我们可以在中间件做一些拦截处理。
中间件常用模型
全局中间件
这个是在服务启动就开始注册,全局意味着所有API接口都会经过这里。Gin的中间件是通过Use
方法设置的,它接收一个可变参数,所以我们同时可以设置多个中间件。
首先定义如下
go
复制代码
// 1.创建路由
r := gin.Default() //默认带Logger(), Recovery()这两个内置中间件
r:= gin.New() //不带任何中间件
// 注册中间件
r.Use(MiddleWare())
r.Use(MiddleWare2())
注意的是
gin.Default()
默认使用了Logger
和Recovery
中间件,其中:Logger中间件将日志写入gin.DefaultWriter
,即使配置了GIN_MODE=release。Recovery中间件会recover
任何panic
。如果有panic的话,会写入500响应码。如果不想使用上面两个默认的中间件,可以使用gin.New()
新建一个没有任何默认中间件的路由。
go
复制代码
// 定义中间
func MiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
fmt.Println("中间件开始执行了")
// 设置变量到Context的key中,可以通过Get()取
c.Set("request", "这是中间件设置的值")
status := c.Writer.Status()
fmt.Println("中间件执行完毕", status)
t2 := time.Since(t)
fmt.Println("time:", t2)
}
}
然后启动我们的服务,访问任意一个接口可以看到输出如下
这是请求先到了中间件,然后在到我们的API接口。在中间件里可以设置变量到Context的key中,然后在我们的API接口取值。
go
复制代码
r.GET("/", func(c *gin.Context) {
// 取值
req, _ := c.Get("request")
fmt.Println("request:", req)
// 页面接收
c.JSON(200, gin.H{"request": req})
})
这时候在访问就可以看到中间件设置的值是
next
方法是在中间件里面使用,这个是执行后续中间件
请求处理的意思(含没有执行的中间件和我们定义的GET方法处理,如果连续注册几个中间件则会是按照顺序先进后出的执行,遇到next就去执行下一个中间件里的next前面方法
。
go
复制代码
// 执行函数
c.Next()
// 中间件执行完后续的一些事情
局部中间件
局部中间件意味着部分接口才会生效,只在局部使用,这时候访问http:127.0.0.1:8000/ 才会看到中间件的日志打印,其他API接口则不会出现。
go
复制代码
//局部中间件使用
r.GET("/", MiddleWare(), func(c *gin.Context) {
// 取值
req, _ := c.Get("request")
fmt.Println("request:", req)
// 页面接收
c.JSON(200, gin.H{"request": req})
})
gin内置中间件
go
复制代码
func BasicAuth(accounts Accounts) HandlerFunc
func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc
func Bind(val interface{}) HandlerFunc
func ErrorLogger() HandlerFunc
func ErrorLoggerT(typ ErrorType) HandlerFunc
func Logger() HandlerFunc
func LoggerWithConfig(conf LoggerConfig) HandlerFunc
func LoggerWithFormatter(f LogFormatter) HandlerFunc
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc
func Recovery() HandlerFunc
func RecoveryWithWriter(out io.Writer) HandlerFunc
func WrapF(f http.HandlerFunc) HandlerFunc
func WrapH(h http.Handler) HandlerFunc
总结
通过自定义中间件,我们可以很方便的拦截请求,来做一些我们需要做的事情,比如日志记录、授权校验、各种过滤等等。
这里给大家分享一份Python全套学习资料,包括学习路线、软件、源码、视频、面试题等等,都是我自己学习时整理的,希望可以对正在学习或者想要学习Python的朋友有帮助!
CSDN大礼包:全网最全《全套Python学习资料》免费分享🎁
😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓
1️⃣零基础入门
① 学习路线
对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
② 路线对应学习视频
还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~
③练习题
每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!
因篇幅有限,仅展示部分资料
2️⃣国内外Python书籍、文档
① 文档和书籍资料
3️⃣Python工具包+项目源码合集
①Python工具包
学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!
②Python实战案例
光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!
③Python小游戏源码
如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!
4️⃣Python面试题
我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
5️⃣Python兼职渠道
而且学会Python以后,还可以在各大兼职平台接单赚钱,各种兼职渠道+兼职注意事项+如何和客户沟通,我都整理成文档了。
上述所有资料 ⚡️ ,朋友们如果有需要 📦《全套Python学习资料》的,可以扫描下方二维码免费领取 🆓
😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓