应用层: HTTP 与 HTTPS协议

目录

http请求格式:

首行:

method: 请求方法.

URL: 统一资源定位符, 俗称网址.  

version: http协议版本号

头部:

空行:

正文:

http响应格式:

首行:

头部:

cookie机制:​

session机制:

空行:

正文:

HTTP服务器实现:

HTTPS协议:

https协议的加密流程:

身份验证:

数据加密:

对称加密:

非对称加密:

混合加密:

SSL加密流程:


http是应用层的协议, 应用程序之间数据格式的约定统一格式, 由程序员们自己约定

协议可以用自定制协议也可以是已有的、优秀的知名的协议.

http协议就是大佬们弄好的针对典型应用的知名的nb的协议.(应用层的知名的协议还有: http 超文本传输协议,https 解密的http, ftp 文件传输协议, smtp 邮件传输协议, dns 域名解析协议)

自定制协议: 我们可以自己随便定义使用的数据格式,  但是要高效就得考虑: 序列化,反序列化的传输性能和解析性能问题. 序列化后的二进制数据越短传输性能越好, 序列化和反序列化的过程越简单解析性能越好. 通常使用结构体的二进制序列化解析性能非常高 (通过的是结构体的特性,对成员变量的赋值就能实现数据在内存中的序列化.) 但是结构体方式的序列化存在缺陷: 不同平台 位段的使用、字节对齐 不同.

http协议是应用层协议,在传输层用的tcp协议.也就是说http服务器也就是tcp服务器. http协议是个简单的请求-响应协议,一次请求一个响应. http是明文字符串传输协议(2.0版本前), 即协议组织的请求响应数据是人能看得懂的.

http请求格式:

包括首行, 头部字段, 空行, 正文四个部分

应用层: HTTP 与 HTTPS协议_第1张图片

首行:

首行就是请求报文中的第一行, 包含三个要素: method url version\r\n, 三个要素之间用空格间隔.

一个完整的首行就例如: 

GET http://www.baidu.com:9090/path?key=val&key=val#ch HTTP/1.1\r\n

(\r\n是换到下一行行首, 不是一个字符串的意思)

method: 请求方法.

请求方法描述了这个请求的目的, 比如是获取数据还是提交数据或者是修改数据, 删除数据. 典型的有:

GET: 获取数据, 没有正文, 也可以提交少量数据, 提交的数据在url中,有安全隐患长度也有限制.

POST: 提交数据, 提交的数据在正文中, 长度无限制.

GET和POST有什么区别:  本质上没有区别, 细节上有些区别, 最终还是取决于程序员的设定. 通常数据放的位置不同(安全与否); 语义区别,一般get获取数据,post提交数据; get一般设置等幂的,post不设置为等幂(某个请求执行一次和执行多次没有区别就称之为为等幂).

HEAD: 与GET类似,但响应不要正文数据,只要头部描述.

URL: 统一资源定位符, 俗称网址.  

较为完整的URL格式:

协议方案名称://用户名:密码@域名或IP地址:端口/资源路径?查询字符串#片段标识符

协议方案名称: 描述通信所用协议.

用户名:密码 :现在已经很少用了,因为之间把用户名和密码放在网址上是不安全的.

域名或ip地址: 服务器的别名, 方便人记忆的(比如baidu.com), 通过域名解析得到服务器ip地址.

端口: 域名(或ip地址)和端口定位描述了网络中的某一台主机上的某个进程, http默认80端口,https-443端口

/资源路径: 描述指定路径下的某个实体资源(功能), / 是服务器里的相对根目录. 域名(或ip地址)+端口+/资源路径,就决定了客户端这个请求的是网络中指定主机上的指定资源, 且这个请求由哪个进程处理. 比如: http://cn.bing.com/search, 必应服务器的查询功能.http://cn.bing.com/login, 必应服务器的登录

查询字符串: 客户端提交给服务端的少量数据, 格式为(键值对): key=val&key=val ...

为了防止提交的数据中有特殊字符(字母外的字符)比如? 会造成特殊字符与url中的间隔符产生歧义, 所以特殊字符需要进行转义, 即url编码,urlencode.

urlencode: 遇到特殊字符将其每个字节转换为16进制的数字字符, 比如我们搜索c++在请求报文中的url中的查询字符串中的 ' + ' 就转成ascii表十六进制的2B. 并且转换后为了表示这是特殊字符,加前缀标识%,比如c++转为c%2B%2B

urlencode: url解码,对url编码后的数据解码, 遇到%,则将%后的两个字符的16进制ascii值转换为特殊符号.

片段标识符: html网页中的标签id,加了片段标识符可以让网页直接滑动到指定位置.

version: http协议版本号

协议版本后的 \r\n 就是转到行首,换行,就像回车换行到下一行行首.

0.9版本: 不成成熟的版本, 只有GET的方法,协议格式不完善.

1.0版本: 规范了协议格式, 有了HEAD,POST,GET方法, 支持了多媒体数据流传输.

1.1版本: 支持更多请求方法和头部字段, 有了长连接管理和缓存管理.

2.0版本: 由于http协议臃肿,重新进行了设计,有点推翻重建内维尔, 解决了一些典型,性能的问题.

1.0相较0.9: 主要规范了协议格式, 支持了更多更能和数据传输方式..

1.1相较1.0: 主要在性能上改进.缓存控制: 一些资源在没有改变则不需要重新再次传输. 

长连接的改进: 短链接: 一次连接只处理一次请求, 即建立连接,发送请求,得到响应,断开连接. 而下次(每次)请求得再次新建一个链接.  长连接: 一次链接中可以进行多次请求. 长连接相较于短链接节省了大量的来连接建立时间

1.1版本的长连接是管线化思想, 2.0版本的长连接是多路复用思想.

管线化:相较于传统长连接,请求连续发送同时处理,节省处理时间,按序响应
缺陷:响应必须与请求顺序一致,存在队头阻塞问题
队头阻塞:如果第一个资源处理时间长,就算后边的资源准备好了也不能响应

2.0版本中的长连接多路复用: 解决了队头阻塞问题,每个响应中包含对应的请求描述,因此哪个资源准备好了就可以直接响应应用层: HTTP 与 HTTPS协议_第2张图片
2.0相较1.1:

1.从明文字符串传输改为二进制传输
⒉支持服务端主动推送依赖数据(以前是一次请求一次响应),一次请求,可以响应多个数据

3.多路复用在响应头部中添加请求信息,不用按序响应,解决队头阻塞问题
4.保存以前传输中没有出现的头部字段,相同的头部字段不同每次都重新传输了

头部:

头部字段以 key: val 组成的多个键值对字段组成(val前有空格), 每个键值对以\r\n结尾, 是关于请求或正文的关键描述信息. key是字段类型名, key: val键值对就像 学校: 某某某大学 这样,val描述key, 常见的字段有:

Host: 服务器域名或地址信息.

Connection: 长短连接的管理.(Connection: keep-alive表示长连接,Connection: close表示短链接)

User-Agent: 告诉服务端 客户端的浏览器版本以及系统版本信息(根据版本服务端会相应不同的渲染页面等..)

Accept: 告诉服务端客户端自己能够接收什么样的响应数据

Referer: val中包含一个连接,表示的是当前请求的来源页面连接(比如百度给某网站打广告, 该网站可以通过referer统计从百度点链接进来的人数,看看广告打得值不值等..)

Content-Length: 正文描述,描述正文有多长
请求或者响应必须完整才能处理,不完整就会现: 多个请求或响应连续发送,就会存在粘包问题(多个数据连接到一起无法区别每个数据的起始和结尾, 取长就可能把下一个连着的包的首行头部啊什么也当成前一个包的正文.取短就取少了咯). 这个字段就是用于解决http粘包问题, 根据格式先取出头部,根据头部中的content-length字段确定正文长度然后取出指定长度正文,解决粘包

Content-Type: 正文类型描述,决定了对端如何处理正文数据
 

空行:

空行就是\r\n独占一行, 用于间隔头部与正文. 当头部自动逐个取出,而某个字段只有\r\n时,则表示头部结束. 也可以理解为头部最后一个字段结尾为\r\n\r\n.

正文:

提交给服务端的数据, GET没有这部分.POST提交的数据就放在正文中.(GET放url中)

一个简单的http请求:

应用层: HTTP 与 HTTPS协议_第3张图片

http响应格式:

应用层: HTTP 与 HTTPS协议_第4张图片

首行:

也包含三个要素: 协议版本 响应状态码 状态码描述    也是以空格为间隔.最后有对\r\n

协议版本: 就是上边说的0.9/ 1.0/ 1.1/ 2.0

响应状态码: 一个三位数的数字, 每个数字代表不同的请求结果

1xx: 1开头的响应状态码, 描述信息或是协议切换协商, 比如101是协议切换响应, 服务器同意客户端的切换协议请求就会响应101

2xx: 描述请求成功处理, 比如200对应的状态码描述就是OK

3xx: 重定向, 当一个资源链接发生改变,但是保持原链接依然可用则将原链接重定向到新的链接,与Location头部字段搭配, 客户端看到3xx的响应,会请求跳到Location字段中的网址.

301-永久-下次请求时直接请求新链接; 302-临时-下次请求时依然请求原链接; 304读取浏览器缓存

4xx: 描述客户端错误, 400-请求格式错误,  403-服务器收到请求但拒绝提供服务. 404-请求的资源不存在.

5xx: 描述服务端错误, 500-服务器内部错误;  502-代理服务器错误; 504-代理请求超时

状态码描述: 对状态码的简单描述, 是一些英文单词,比如 200 OK,OK就是对200这个响应状态码的简单描述. 即请求得到的响应结果,请求成功了就是OK.  404 NOT FOUND.  状态码描述是无意义的,我们自己写响应时,后面的状态码描述和状态码对不上也不会报错.

头部:

也是由多个 key: val 键值对组成, 每个键值对以\r\n结尾, 也是用于描述正文或响应信息.

也有Connection-Length: 正文长度,Connection-Type: 正文类型. 之类的头部字段.

Location: 与3xx的响应码搭配使用, val是一个重定向的新链接.

Set-Cookie: 与请求的Cookie头部字段搭配使用, 用于实现http的cookie机制.

cookie机制:

http是一个无状态的协议, 早期版本中短连接,一次通信连接就会断开,但是随着协议的发展, 客户端的标识状态越来越重要,比如购物︰登录会告诉对方客户端的身份信息,但是当你本次通信完毕链接就断开了,下次买东西的时候依然需要重新建立连接发送客户端认证信息.
因此就有cookie机制,服务端将客户端的一些状态信息通过Set-Cookie字段发送给客户端,客户端将这些信息保存到cookie文件中,在下次请求服务器的时候将cookie信息从cookie文件中读取出来,通过Cookie字段发送给服务器,服务器收到之后,就能了解客户端的身份状态信息了。这样,之后每次打开购物页面就不需要每次都要输入账号和密码了.

cookie的一些属性: 

应用层: HTTP 与 HTTPS协议_第5张图片

cookie就是用于在http协议中持续维护客户端通信状态的机制

应用层: HTTP 与 HTTPS协议_第6张图片

session机制:

当客户端发送认证信息到服务器,服务器会为每个客户端创建一个会话,会话信息中包含有客户端的身份以及各项状态信息,然后将其保存在服务器数据库中,每个会话都有一个唯一ID(不重复的长整型数),然后将session_id作为Set-Cookie的字段值传输给客户端,客户端在下次请求服务器的时候就把session_id发送给服务器服务器通过session_id就能在数据库中找到会话信息进而获取到客户端的状态信息, 这样客户端的敏感信息就不用在网络上持续传输了.
cookie是客户端状态信息保存在客户端的, session是客户端状态信息保存在服务端

session有效期默认是30分钟, 当访问增多大量的session会占用服务器的性能. 

Session可以存放各种类别的数据,cookie只能存储字符串.

空行:

\r\n, 一样, 用于间隔头部和正文

正文:

响应给客户端的数据,  一个简单的响应包示例: 

应用层: HTTP 与 HTTPS协议_第7张图片

HTTP服务器实现:

首先使用我们之前写的tcp服务器, 我选择了多线程版的, 进行小修改只需要改这里:

应用层: HTTP 与 HTTPS协议_第8张图片

 

 效果: 应用层: HTTP 与 HTTPS协议_第9张图片

应用层: HTTP 与 HTTPS协议_第10张图片

 抓包工具抓到的: 下边那栏是响应应用层: HTTP 与 HTTPS协议_第11张图片

如果把响应修改成302 FOUND:

应用层: HTTP 与 HTTPS协议_第12张图片

会直接跳到百度的页面. 

应用层: HTTP 与 HTTPS协议_第13张图片

 如果响应码是404: 应用层: HTTP 与 HTTPS协议_第14张图片

自己弄的404页面, 这里俺不会就用这个了:

应用层: HTTP 与 HTTPS协议_第15张图片

HTTPS协议:

https本质上还是http协议, 但是进行了一层加密: SSL加密. 是针对tcp协议的.

不同点: 1.加密了当然安全性更高了. 2.http使用80端口, https使用443端口.

https协议的加密流程:

https协议的加密其实就是SSL加密, 加密分为两个方面: 身份验证和数据加密

身份验证:

双向认证: 引入一个双方都信任的第三方权威机构,必须是双方都信任的机构,双方到权威机构颁发一个身份证书,在通信前将证书发送给对方对方根据证书中的信息(我是谁,在哪里颁发的证书,有效期…….)。判断对方的身份,并且去第三方权威机构进行认证通过后则身份验证成功。然后再进行通信

而我们平时的浏览器访问只是单项验证: 客户端验证服务器

数据加密:

对称加密:

双方使用相同的密钥进行加密解密叫对称加密.

通信前将秘钥交给对方,自己使用秘钥进行数据加密,对方使用相同秘钥进行数据解密。不能一直使用某种秘钥,很容易被破解(暴力破解)但每次通信前动态协商也存在安全隐患, 因为协商秘钥也容易被劫持;

好处: 加密解密通常效率比较高.  缺点: 安全度低

非对称加密:

加密, 解密的密钥不同叫非对称加密.

生成一对秘钥(公钥与私钥),其中公钥用于进行数据加密,私钥用于对公钥加密的数据进行解密(公钥加密的数据使用公钥是无法解密的),因此通信前,将公钥传递给对方,对方使用公钥进行数据加密,数据到达后自己使用私钥进行解密,得到数据
安全度非常高: 不怕公钥被劫持;    但是也有缺陷:加密解密效率很低

混合加密:

先进行非对称加密,通信前,将公钥交给对方,对方用公钥加密对称秘钥的协商过程,这样对称秘钥就无法被劫持了,协商完毕之后,使用协商出的对称秘钥进行通信。通过这种方式既保证了安全,也保证了效率。
 

SSL加密流程:

1.服务器(需要被验证身份的一方),生成—对秘钥(公钥与私钥)

⒉.服务器带着公钥,去权威机构生成一个证书(我是谁,权威机构是谁,有效期....公钥)

3.通信时,在tcp建立连接成功后,将证书首先发送给客户端

4.客户端收到证书,进行解析,得到各项数据,然后到权威机构进行服务器身份验证

5.验证成功,使用公钥加密自己所支持的对称加密算法列表以及一个随机数发送给服务器

6.服务器收到公钥加密的信息后,使用私钥进行解密,得到了客户端支持的算法列表以及随机数

7.服务器将自己支持的算法列表以及一个随机数发送给客户端, 这步不需要加密,因为劫持了也没用

8.客户端与服务器各自根据算法列表以及自己和对方的随机数生成一个对称秘钥9.往后通信使用对称秘钥进行加密通信。
应用层: HTTP 与 HTTPS协议_第16张图片

你可能感兴趣的:(http,网络协议,网络)