网络 应用层 HTTP的认识及实现(模拟实现一个简单的服务器)_http应用服务实现

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

概念

应用层:是TCP/IP的顶层,通过使用传输层提供的服务,直接向用户提供服务,是TCP/IP网络与用户之间的界面或接口。应用层是直面程序员的一层,因为应用层是程序员自己写的,因此应用层的协议都是程序员自己定的

应用层上的典型应用包括web浏览器、电子邮件、文件传输访问和远程登录等。

序列化和反序列化

序列化:将各个数据对象按照指定的协议组织成为持久化存储/数据传输的二进制数据串
反序列化:将二进制数据串按照指定协议解析得到各种数据对象
常用的序列化方式:json序列化/protobuf/二进制序列化
序列化方式的评价标准:解析数据的性能、传输数据的性能、和可读性

协议

应用层有两个重要的协议:一个是自定制协议,一个是超文本传送协议HTTP
自定义协议:程序员自己根据自己的应用场景的特点,定义协议(数据的格式/数据的描述信息)

如何制定自定制协议

我们以一个简单的网络版计算器来举例,计算机功能为:客户端发送两个数字以及一个运算符给服务端,服务端获取到数据后然后进行运算,将运算结果返回给客户端。
有两种约定方案可以实现:
方案一:1、客户端发送一个型如"1+1"的字符串;2、这个字符串的两个操作数都是整形;3、两个数字之间会有一个字符是运算符,运算符只能是+;4、数字和运算之间没有空格
方案二:采用结构体构造二进制数据串,将三个数据都封装到一个结构体中

struct cal_t
{
	int num1;
	int num2;
	char op;
};

这种方案是非常常用的,将多个对象封装成一个对象,当客户端收到数据时就不用再多此一举得去解析,而是按指定格式去取数据;前4个字节数数据1,前8个字节的后4字节是数据2,最后一个字节就是运算符。用起来非常方便
在这里插入图片描述
socket封装的对象中添加结构体信息

typedef struct
{
    int num1;
    int num2;
    char op;
}cal_t;

客户端:

cal_t cal;
cal.num1 = 12;
cal.num2 = 34;
cal.op = '+';
send(fd, (char\*)&cal, sizeof(cal_t), 0);

服务端:

cal_t cal;
recv(fd, (char\*)&cal, sizeof(cal_t), 0);
printf("%d % c %d\n", cal.num1, cal.op, cal.num2);

这样子就可以实现自定制协议

知名协议----HTTP协议

HTTP是当今互联网应用中使用最广泛的应用层协议,也是应用程序之间远程通信所采用比较多的协议,用来在浏览器和WWW服务器之间传送超文本的协议。基于浏览器的HTMP、XML、JSON、等格式的文本都是通过HTTP进行传输的。它非常便捷,客户向服务端发送请求服务时,只需要发送路径、参数以及请求方法即可。请求方法常用的右GET、POST、UDPATE、DELETE等,它们组成RESTful架构风格的不可缺一的部分

网址:例如我们平时打开的网页都有相对应的网址https://www.baidu.com/。网址是统一资源定位器,简称URL,定位网络中某台主机上的某个资源

URL的组成

协议方案名称://认证用户名:认证密码@服务器IP地址:服务器处理进程端口/请求的资源路径?查询字符串#片段标识符

http://username:password@www.baidu.com:80/index.html?name=WhiteShirtI&age=21#id

协议方案名称(常用):通信协议,通常使用http

认证用户名:认证密码(少用):用户的账号密码

服务器IP地址(常用):我们看到的不一定是IP地址,也可能是一个域名,也就是服务器的别名,通过域名解析服务器就能得到服务器的IP地址

服务器处理进程端口(常用):web服务器默认http服务器端口是80端口,默认不显示

/请求的资源路径(常用):资源在服务器上的路径,这里的/是http的根目录,但是是一个服务器的相对根目录,只是一个子目录。原因是省去前面重要的目录地址信息,防止用户访问

查询字符串:客户端提交给服务端的一些数据,由key=val&key=val形式的键值对组成的;查询的字符串不能出现特殊字符:因为url中特殊字符都是有特殊含义的,一旦提交的数据中有特殊字符,就会造成数据二义,因此若要提交的数据中有特殊字符,则需要进行数据转义;urlencode:url解码,提交的数据中不能出现特殊字符,一旦出现就要进行转义。将特殊字符每一个字节转换为16进制的数字字符,并且使用%前缀作为转义;+ 转义成 %2B ;解释:在ASSIC中+是代表数字43,转换成16进制就是2B
在这里插入图片描述

urldecode:url解码,在url中遇到%,则认为其后两个字符需要转义,将第一个字符转换成数字乘以16,加上第二个字符转换的数字。%2B 转义成 + ;解释:2*16+11=43, 将43转换为ASSIC码对应的符号

片段标识符:html中的一个标签id,直接跳转到页面的某个位置

HTTP协议请求格式

HTTP协议请求包含四个内容:首行、请求头部、空行、正文

首行

GET https://blog.csdn.net/qq_44443986?spm=1011.2124.3001.5113 HTTP/1.1 以空格进行间隔包含三个要素,并且最终以\r\n作为结尾
第一要素:请求方式:GET/POST/HEAD/PUT/DELETE/CONNECT/OPTIONS/TRACE/PATCH

  • GET-请求指定的页面信息,并返回实体主体,没有请求正文。也可以通过url中查询字符串向服务器提交数据,但是数据不安全 且 url长度有限制(各个服务器应用商的限制)
  • POST-向指定资源提交数据进行处理请求(例如提交表单或者上传文件),且提交的数据在请求正文中,相对GET比较安全 且无长度限制。
  • HEAD-类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头

第二要素:URL:网址信息
第三要素:协议版本:HTTP/1.1/0.9/1.0/2.0

  • HTTP/0.9-这时候的http仅用于传输html数据,并且只有GET请求方法,并且没有协议标准格式
  • HTTP/1.0-正式规定了http协议格式,并且增加了多种请求方法,并且支持了不同文件格式的数据流
  • HTTP/1.1-在1.0的基础上增加了更多请求方法和头部描述信息,并且支持了长连接管线化传输。(http基于在传输层tcp实现通信,短连接指的是建立连接后发送一个请求,得到响应之后就关闭连接;长连接指的是发送请求得到响应后并不会关不连接,当下次再来一次请求是还会使用当前这个连接,但这个连接不是永久存在的,当两端长时间没有交往时会自动断开;管线化传输指的是将多个HTTP请求整批提交的技术,而在传送过程中不需先等待服务端的回应 <响应的顺序必须与请求的顺序保证一致:1请求到2请求,必须等到1响应了2才能响应,存在线头阻塞问题>
  • HTTP/2.0-采用二进制流传输,并且支持多路复用,并且允许服务端主动推送数据 。(服务端主动推送数据是指请求一次,服务端会一次性推送所有数据,而不是一个请求,对应一个响应的数据;<利用多路复用,头部中标识了自己属于哪个流,解决了线头阻塞的问题,同时也提高了网络速度的利用率>)
头部

请求头部用来描述本次请求的关键字段信息,由key:val形式的键值对组成,并且每个键值对以\r\n作为结尾

  • Connection-控制长/短连接
  • Cache-Control-缓存控制
  • User-Agent-客户端的属性
  • Accept-描述自己所能接收的数据属性
  • Content-Length-描述正文长度
  • Content-type-描述正文的数据类型
  • Get请求方式专属信息:Cookie-带有客户端的身份、状态等信息,客户端每次通信从cookie文件读取数据,通过cookie向服务端传递信息,(用于维护客户端状态信息)但是不够安全。Post则是将这些信息保存在正文中(安全)
空行

目的是间隔头部与正文,\r\n。接收http数据的时候,当连续接收两个\r\n的时候,则就认为头部到此结束。

正文

先获取完整头部,通过头部中的Content-Lenght获取正文长度,然后获取指定长度的正文,通过这种方式每次获取完整一条http请求数据
正文就是提交给服务端的数据

HTTP协议响应格式

HTTP协议响应包含四个内容:首行、请求头部、空行、正文

首行

HTTP/1.1 200 OK 以空格进行间隔包含三个要素,并且最终以\r\n作为结尾
第一要素:版本协议
第二要素:响应状态码
响应状态码是一个数字,这个数字表示本次的请求后服务端所做出响应的结果,这个结果分为五大类型:

  • 1xx:描述信息-服务器收到请求,需要请求者继续执行操作
  • 2xx:请求成功-操作被成功接收并处理;典型的有200-请求成功。一般用于GET与POST请求
  • 3xx:重定向-要求客户端重新请求新的位置;典型的有301-永久移动、302-临时移动
  • 4xx:客户端错误-请求包含语法错误或无法完成请求;典型的有400-请求错误;404-请求的资源不存在
  • 5xx:服务端错误-服务器在处理请求的过程中发生了错误;典型的有500-服务器内部错误,无法完成请求;502-服务器作为网关或代理尝试执行请求时,从远程服务器接收到了一个无效的响应;504-服务器作为网关或代理,但是没有及时从远程服务器收到请求,响应超时

第三要素:描述状态码
对状态码的描述信息,可以是官方文档对应的描述信息,也可以自定义描述信息

HTTP状态码大全

头部

响应头部用来描述本次响应的关键字段信息,由key:val形式的键值对组成,并且每个键值对以\r\n作为结尾

  • Connection-控制长/短连接
  • Content-type-描述正文的数据类型
  • Server-包含有关用作原始服务器处理请求的软件信息
  • Transfer-Encoding-指定实体正文传输给客户端的方式,例如chunked-分块传输,将一个正文分为多块进行传输
  • Expires-缓存过期时间
  • Cache-Control-缓存控制
  • Set-Cookie-服务端通过set-cookie向客户端传递信息,会被保存在客户端浏览器的cookie文件中

由于cookie的使用不够安全,从而引入了Session,搭配cookie使用
Session-会话:服务端会为每个登录的客户端创建会话session,会话session保存了一些会话信息(客户端身份、状态信息等),并且session保存在服务端。可以通过cookie将session id返回给客户端,客户端每次通信都会通过cookie带有自己的session id,服务端就通过session id知道这是哪一个客户端了

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

…(img-SWFUY5H8-1715887106694)]
[外链图片转存中…(img-ZXEAqQNl-1715887106694)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值