HTTP和HTTPS的运行逻辑和IO网络模型的多路复用逻辑整理

作者: admin 分类: 服务器 发布时间: 2019-11-01 13:59  阅读: 36 views

1、HTTP – 超文本传输协议

HTTP是一种协议,允许web服务器和浏览器通过互联网进行发送和接受数据。它是一种请求和响应协议。客户端请求一个文件二服务器响应请求。HTTP使用可靠的TCP连接(TCP默认使用80端口)

HTTP协议是基于请求/响应范式的。

HTTP的请求格式:统一资源标识符、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。

------------------------------
请求方法URLHTTP协议的版本号
提交的元信息
**空行**
实体
------------------------------

HTTP的响应格式:一个状态行包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。

--------------------------------
HTTP协议的版本号应答状态码应答状态码说明
接收的元信息
**空行**
实体
--------------------------------

image

HTTP协议的内部操作过程

首先,简单介绍基于HTTP协议的客户/服务器模式的信息交换过程,它分四个过程,建立连接、发送请求信息、发送响应信息、关闭连接

1.建立连接

连接的建立是通过申请套接字(Socket)实现的。客户打开一个套接字并把它约束在一个端口上,如果成功,就相当于建立了一个虚拟文件。以后就可以在该虚拟文件上写数据并通过网络向外传送。

2.发送请求

打开一个连接后,客户机把请求消息送到服务器的停留端口上,完成提出请求动作。

请求行中的方法描述指定资源中应该执行的动作,常用的方法有GET、HEAD和POST。

请求头信息又称为元信息,即信息的信息,利用元信息可以实现有条件的请求或应答。

常用的头信息包括:

Accept:浏览器可接受的MIME类型。
Accept Charset:浏览器可接受的字符集。
Accept Encoding:浏览器能够进行解码的数据编码方式,比如gzip。
Accept Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。
Authorization:授权信息,通常出现在对服务器发送的WWW - Authenticate头的应答中。
Connection:表示是否需要持久连接。如果Servlet看到这里的值为“Keep Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。
Content Length:表示请求消息正文的长度。
Cookie:这是重要的请求头信息之一。
From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它。
Host:初始URL中的主机和端口。

3.发送响应

服务器在处理完客户的请求之后,要向客户机发送响应消息。

4.关闭连接

客户和服务器双方都可以通过关闭套接字来结束TCP/IP对话

可以通过浏览器检查当前请求的信息

General:

Request URL: https://www.cnblogs.com/aspirant/ajax/GetCommentCount.aspx?postId=9166944&_=1572503330473
Request Method: GET
Status Code: 200 
Remote Address: 101.37.113.127:443
Referrer Policy: origin

Response Headers:

content-length: 1
content-type: text/plain; charset=utf-8
date: Thu, 31 Oct 2019 06:28:50 GMT
server: Tengine
status: 200

Request Header:

:authority: www.cnblogs.com
:method: GET
:path: /aspirant/ajax/GetCommentCount.aspx?postId=9166944&_=1572503330473
:scheme: https
accept: text/plain, */*; q=0.01
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
cookie: _ga=GA1.2.733761148.1572423263; _gid=GA1.2.774448409.1572423263; __gads=ID=a758392c7b26a562:T=1572423263:S=ALNI_Mao6c2uLgR4FvsnOBlGjf2C9WV0vg
referer: https://www.cnblogs.com/
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
x-requested-with: XMLHttpRequest

Query String Paramters:

postId: 9166944
_: 1572503330473

2、HTTPS超文本传输安全协议

HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。

HTTPS 协议是由 HTTP 加上 TLS/SSL 协议构建的可进行加密传输、身份认证的网络协议,主要通过数字证书、加密算法、非对称密钥等技术完成互联网数据传输加密,实现互联网传输安全保护。

设计目标主要有三个。

1. 数据保密性:保证数据内容在传输的过程中不会被第三方查看。就像快递员传递包裹一样,都进行了封装,别人无法获知里面装了什么。

2. 数据完整性:及时发现被第三方篡改的传输内容。就像快递员虽然不知道包裹里装了什么东西,但他有可能中途掉包,数据完整性就是指如果被掉包,我们能轻松发现并拒收。

3. 身份校验安全性:保证数据到达用户期望的目的地。就像我们邮寄包裹时,虽然是一个封装好的未掉包的包裹,但必须确定这个包裹不会送错地方,通过身份校验来确保送对了地方。

HTTPS的运行原理

① 客户端将它所支持的算法列表和一个用作产生密钥的随机数发送给服务器 ;
② 服务器从算法列表中选择一种加密算法,并将它和一份包含服务器公用密钥的证书发送给客户端;该证书还包含了用于认证目的的服务器标识,服务器同时还提供了一个用作产生密钥的随机数;
③ 客户端对服务器的证书进行验证(有关验证证书,可以参考数字签名),并抽取服务器的公用密钥;然后,再产生一个称作 pre_master_secret 的随机密码串,并使用服务器的公用密钥对其进行加密(参考非对称加 / 解密),并将加密后的信息发送给服务器;
④ 客户端与服务器端根据 pre_master_secret 以及客户端与服务器的随机数值独立计算出加密和 MAC密钥(参考 DH密钥交换算法);
⑤ 客户端将所有握手消息的 MAC 值发送给服务器;
⑥ 服务器将所有握手消息的 MAC 值发送给客户端。

补充:1.http发展历程

image

单线程 -> 多线程 -> select模型 -> epoll

补充:2.网络IO模型

  • 同步模型(synchronous IO)
    1. 阻塞IO(bloking IO) 【BIO】
    2. 非阻塞IO(non-blocking IO) 【NIO】
    3. 多路复用IO(multiplexing IO)
    4. 信号驱动式IO(signal-driven IO)
  • 异步IO(asynchronous IO)
    1. 异步IO 【AIO】
网络IO的本质是socket的读取,socket在linux系统被抽象为流,IO可以理解为对流的操作。对于一次IO访问,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间,所以一般会经历两个阶段:

1. 等待所有数据都准备好或者一直在等待数据,有数据的时候将数据拷贝到系统内核;
2. 将内核缓存中数据拷贝到用户进程中;

多路复用的实现有多种方式:select、poll、epoll

1. select

  • 调用流程
a. 从用户空间将fd_set拷贝到内核空间
b. 注册回调函数
c. 调用其对应的poll方法
d. poll方法会返回一个描述读写是否就绪的mask掩码,根据这个mask掩码给fd_set赋值。
e. 如果遍历完所有的fd都没有返回一个可读写的mask掩码,就会让select的进程进入休眠模式,直到发现可读写的资源后,重新唤醒等待队列上休眠的进程。如果在规定时间内都没有唤醒休眠进程,那么进程会被唤醒重新获得CPU,再去遍历一次fd。
f. 将fd_set从内核空间拷贝到用户空间

  • 优点:两次拷贝耗时、轮询所有fd耗时,支持的文件描述符太小
  • 缺点:跨平台支持

2. poll

  • 调用流程(和select一致)
  • 优点:连接数(也就是文件描述符)没有限制(链表存储)
  • 缺点:大量拷贝,水平触发(当报告了fd没有被处理,会重复报告,很耗性能)

3. epoll

  • 调用流程
a. 当调用epoll_wait函数的时候,系统会创建一个epoll对象,每个对象有一个evenpoll类型的结构体与之对应,结构体成员结构如下。

(rbn,代表将要通过epoll_ctl向epll对象中添加的事件。这些事情都是挂载在红黑树中。
rdlist,里面存放的是将要发生的事件)

b. 文件的fd状态发生改变,就会触发fd上的回调函数
c. 回调函数将相应的fd加入到rdlist,导致rdlist不空,进程被唤醒,epoll_wait继续执行。
d. 有一个事件转移函数——ep_events_transfer,它会将rdlist的数据拷贝到txlist上,并将rdlist的数据清空。
e. ep_send_events函数,它扫描txlist的每个数据,调用关联fd对应的poll方法去取fd中较新的事件,将取得的事件和对应的fd发送到用户空间。如果fd是LT模式的话,会被txlist的该数据重新放回rdlist,等待下一次继续触发调用。


  • epoll的ET/LT
LT:延迟处理,当检测到描述符事件通知应用程序,应用程序不立即处理该事件。那么下次会再次通知应用程序此事件。
ET:立即处理,当检测到描述符事件通知应用程序,应用程序会立即处理。

ET模式减少了epoll被重复触发的次数,效率比LT高。
我们在使用ET的时候,必须采用非阻塞套接口,避免某文件句柄在阻塞读或阻塞写的时候将其他文件描述符的任务饿死

  • 优点:
1. 没有最大并发连接的限制
2. 只有活跃可用的fd才会调用callback函数
3. 内存拷贝是利用mmap()文件映射内存的方式加速与内核空间的消息传递,减少复制开销。(内核与用户空间共享一块内存)
  • 缺点:只有存在大量的空闲连接和不活跃的连接的时候,使用epoll的效率才会比select/poll高

最后放上对IO网络模型的有趣类比

> 阻塞IO, 给女神发一条短信, 说我来找你了, 然后就默默的一直等着女神下楼, 这个期间除了等待你不会做其他事情, 属于备胎做法.

>非阻塞IO, 给女神发短信, 如果不回, 接着再发, 一直发到女神下楼, 这个期间你除了发短信等待不会做其他事情, 属于专一做法.

>IO多路复用, 是找一个宿管大妈来帮你监视下楼的女生, 这个期间你可以些其他的事情. 例如可以顺便看看其他妹子,玩玩王者荣耀, 上个厕所等等. IO复用又包括 select, poll, epoll 模式.

那么它们的区别是什么?
> 3.1 select大妈 每一个女生下楼, select大妈都不知道这个是不是你的女神, 她需要一个一个询问, 并且select大妈能力还有限, 最多一次帮你监视1024个妹子

> 3.2 poll大妈不限制盯着女生的数量, 只要是经过宿舍楼门口的女生, 都会帮你去问是不是你女神

> 3.3 epoll大妈不限制盯着女生的数量, 并且也不需要一个一个去问. 那么如何做呢? epoll大妈会为每个进宿舍楼的女生脸上贴上一个大字条,上面写上女生自己的名字, 只要女生下楼了, epoll大妈就知道这个是不是你女神了, 然后大妈再通知你.
上面这些同步IO有一个共同点就是, 当女神走出宿舍门口的时候, 你已经站在宿舍门口等着女神的, 此时你属于阻塞状态

> 接下来是异步IO的情况
你告诉女神我来了, 然后你就去王者荣耀了, 一直到女神下楼了, 发现找不见你了, 女神再给你打电话通知你, 说我下楼了, 你在哪呢? 这时候你才来到宿舍门口. 此时属于逆袭做法

参考链接:https://www.jianshu.com/p/6a6845464770


   原创文章,转载请标明本文链接: HTTP和HTTPS的运行逻辑和IO网络模型的多路复用逻辑整理

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

更多阅读