计算机网络 (二) 应用层 :HTTP协议详解


应用层负责应用程序之间的数据沟通, 也是我们能直接接触的一层, 我们可以自己编写应用程序,并且定制相关的应用层协议
应用层协议主要分为两个大类,一个是像HTTP,FTP,DNS等知名协议,另一类是自定制协议。

自定制协议

协议,即是约定,是计算机网络中进行数据交换而建立的规则、标准或约定的集合。
对于我们自己编写的应用程序,知名协议未必能够满足我们的需求,所以我们应该结合自己应用的特点,来定制一个更合适的协议。

如何自定制协议呢?简单来说,就是根据数据的格式和描述信息,来指定一个序列化(加密),反序列化(解析)的过程。

序列化:将多个数据对象按照指定的协议进行组织成为持久化存储/数据传输的二进制数据串
反序列化:将二进制数据串通过指定的协议进行解析得到各个的数据对象

源端通过自己定义的协议,将数据按照某种方法进行序列化成二进制数据串。对端接受数据时,只有按照这个协议反序列化才能解析出原来的数据。

常用的序列化方法:结构体二进制序列化,json序列化,protobuf序列化等


虽然我们可以自己定义协议,但是计算机界有一句话,“不要重复造轮子”,已经有很多大佬制定了一些非常实用的协议供我们直接实用,例如HTTP,FTP等, 所以若非必要,可以直接使用这些协议。

这里就主要介绍HTTP协议。

HTTP协议

HTTP协议,即超文本传输协议,是用于从万维网服务器传输超文本到本地浏览器的传送协议。下面就来介绍HTTP的组成与特性

HTTPS协议,现在几乎使用的都是HTTPS,HTTPS基于HTTP协议,通过SSL或TLS提供加密处理数据,其实就是披着SSL外壳的HTTP协议,其本质还是HTTP。


URL

一提到HTTP协议,少不了的就是最重要的URL
URL:即统一资源定位符,用于在网络中定位某台主机上的某一个资源,也就是我们通常所说的网址。
那么是怎么通过URL来定位资源的呢?
URL由以下几部分组成
协议://用户名:密码@服务器ip地址:服务器端口/文件路径?查询字符串#片段标识符

协议:请求需要使用的协议,现在通常为http,https
用户名密码:认证用户的用户名密码,为了安全一般都不会显示。
服务器地址:这里通常都不会是ip地址,而是域名,通过域名解析服务器就能够得到服务器的ip地址。
服务器端口:http协议的端口默认是80,但也可以选择其他的,默认是不显示的。
文件路径:即请求的资源在服务器上的路径
查询字符串:客户端请求中的额外参数,由key=value的键值对组成,以&作为分隔符
片段标识符:html的标签id,可以直接跳转到页面的某个位置

更详细的可以参考这篇博客
快速搞懂URL的构成

这里就拿b站举例子
在这里插入图片描述

同时对于?,#,/,:等特殊字符,会通过urlencode的方式进行转义。转义的规则如下:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式


HTTP协议的特点

1. HTTP是无连接:
无连接的含义是限制每次连接只处理一个请求。服务端处理客户端的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

2. HTTP是灵活的:
只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。通过头部中的Content-Type来标记正在传输的类型

3. HTTP是无状态的
无状态是指对于事务处理没有记忆能力,服务器不知道客户端是什么状态,即我们给服务器发送 HTTP 请求之后,服务器会根据请求给我们发送数据过来,但是发送完后不会记录任何信息。
无状态是一把双刃剑,如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。而如果服务器不需要先前信息时,它的应答就较快。


HTTP协议版本

HTTP协议有四个版本,分别是0.9、1.0、1.1、2.0。现在大部分用的都是1.1版本

0.9版本:这时的http协议没有标准格式,仅用于传输html(超文本标记语言)数据,而且只有get方法。并且连接方式为短连接
短连接:建立连接,发送一个请求,得到相应后关闭连接
在这里插入图片描述

1.0版本:1.0版本正式规定了HTTP协议格式,并且增加了多重请求方法,并且支持不同文件格式的数据流,同时部分应用商已经开始使用长连接(受限制的长连接)
1.0定义了三种请求方法: GET, POST 和 HEAD方法。
长连接:一次连接可以发送多条请求
在这里插入图片描述

1.1版本:增加了更多的请求方法和头部描述信息,并支持了长连接和管线化传输。
1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法
管线化传输:可以连续发送多个请求,只需要按顺序响应就行,不需要响应后才发下一个请求。
但是还存在约束条件,响应的顺序必须与请求的顺序保持一致,通过队列实现,如果不一致则在队首阻塞。
在这里插入图片描述
2.0版本:采用二进制流传输,并且进行多路复用,允许服务端主动推送数据
多路复用:响应顺序可以与请求的顺序不一致,因为头部中标识了对应的请求信息。提高了信道的利用率
在这里插入图片描述


HTTP协议格式

这里我用fiddler来抓取浏览器中http的数据进行分析
在这里插入图片描述
HTTP请求TP

HTTP响应
在这里插入图片描述
从上面抓取的数据分析,HTTP主要有以下四个部分组成,首行,头部,空行,正文, 并且请求和响应报文细节上都不同。
第一行为首行,紧接着是头部,之后通过一个空行间隔,接下来的则是正文

下面一一分析。


首行

请求首行

[请求方法][URL][协议版本]\r\n
如:
在这里插入图片描述

请求方法

共有GET,、POST 、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE 、CONNECT 等方法。

各种请求的功能

GET:请求指定的页面信息,并返回实体主体。
HEAD:类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT:从客户端向服务器传送的数据取代指定的文档的内容。
DELETE:请求服务器删除指定的页面。
CONNEC:HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS :允许客户端查看服务器的性能。
TRACE: 回显服务器收到的请求,主要用于测试或诊断。
PATCH: 是对 PUT方法的补充,用来对已知资源进行局部更新 。


响应首行

[协议版本][响应状态码][响应状态码描述]\r\n
如:
在这里插入图片描述

响应状态码

响应状态码:表示对于本次请求,服务端做出的响应结果。
例如我们常见的404
在这里插入图片描述

1**:信息,服务器收到请求,需要请求者继续执行操作
2**:成功,操作被成功接收并处理 。常见:200
3**:重定向,需要进一步的操作以完成请求。常见:301(永久重定向)、302(临时重定向)
4**:客户端错误,请求包含语法错误或无法完成请求 。常见:400(请求错误)、404(资源不存在)
5**:服务器错误,服务器在处理请求的过程中发生了错误。常见:500(服务器内部错误)、502(代理请求失败/无效响应)、504(代理请求超时)

状态码描述:对状态码的描述信息,可自定义。


头部

请求头部:描述本次请求的关键字段信息,由key:value形式的键值对组成,并且每个键值对以\r\n作为结尾
如:
在这里插入图片描述

响应头部:描述本次响应的关键字段信息,由key:value形式的键值对组成,并且每个键值对以\r\n作为结尾
如:
在这里插入图片描述
HTTP常用的Header

Content-Type: 数据类型;
Content-Length: 正文的长度 ;
Transfer-Encoding:实体正文的传输方式;
Expires:缓存过期时间;
Referer: 当前页面是从哪个页面跳转过来的;
Location: 3xx重定向的新地址;
Host: 客户端告知服务器,所请求的资源是在哪个主机的哪个端口上;
User-Agent: 声明用户的操作系统和浏览器版本信息;
Set-Cookie:客户端通过Set-cookie向客户端传递的信息,会被保存在客户端浏览器的cookie文件中;
Cookie: 客户端上保存的数据,客户端每次通信时从cookie文件中读取数据,并通过cookie字段向服务端传递信息(用于维持客户端状态信息)
Session:服务端为客户端创建的会话,会话信息中描述了客户端的身份认证信息和状态信息,保存在服务端,可以通过cookie将session id返回给客户端,客户端每次通信都会通过cookie传输带有自己session的id。

Cookie与Session

因为HTTP是无状态的,但在实际情况中,我们还是需要保持状态的
那么如何让HTTP来保持状态呢,答案就是借助Cookie和Session。

举个例子,正好明天就是618,618作为一个大型的购物节,在一天的不同时间段,不同店铺中,会有着许多不同的活动,为了达到最大折扣,我们通常会在一天内多次进入如淘宝、京东等购物网站进行购物,但是因为HTTP是无状态的,所以它并不会记录我们的任何信息,所以我们在每次访问时都需要重新登陆来确认用户的身份,这是一种很麻烦的事情。所以大佬们为HTTP加入了Cookie来帮助其维持状态,在每次通信后,会将服务端的一些临时验证信息保存在客户端的cookie文件中。这样下次通信时,就可以通过读取cookie中保存的验证信息,将其传递给服务端,来维持客户端的状态,这样就可以避免多次登录。

但是Cookie的使用不够安全,因为Cookie保存在客户端(浏览器)。而如果将这些重要的信息保存在本地,则很容易就会被脚本、爬虫等截取,造成不必要的损失,所以Cookie需要搭配Session使用。

Session其实就是服务端为客户端创建的会话,其中描述了客户端的身份认证信息和状态信息,并且将其保存在服务端。服务端每次通信结束后都会将Session id(本次会话的ID)保存在客户端的Cookie中,客户端在下次通信时通过Cookie将保存的Session id传递给服务端,这样服务端就可以通过对应的Session id来查找到客户端的身份认证信息和状态信息,来为客户端维持状态,这样就可以避免重复登录。并且因为Cookie和Session分别保存在客户端和服务端,保证了一定的安全性。

Cookie与session的区别是什么?
Cookie保存在客户端上,是一些临时存储的数据,用于持续与服务端进行信息传递的一种手段。

Session保存在服务端上,是一种会话的控制,会话信息中包含客户端的身份状态信息,通过Cookie传递Session id来查找到对应的身份状态信息,来实现状态维持。


空行

空行即为\r\n,用于间隔头部和正文。因为头部的每一个键值对以\r\n结束,所以一旦连续接受到两个\r\n的时候就代表着头部的接收结束。


正文

请求正文

客户端提交的数据

如上面的:
在这里插入图片描述

响应正文

服务端响应的实体资源
如:
在这里插入图片描述
这里显示为乱码的原因是因为这里用的是https协议,该协议会对响应的内容加密,中间者无法直接查看明文内容


猜你喜欢

转载自blog.csdn.net/qq_35423154/article/details/106812520