HTTP和HTTPS协议的一些基本认知

1. HTTP 协议

  1. 超文本传输协议: 网络中两点之间传输文本、图片、视频和文件等内容的协议
  2. HTTP基于TCP连接
1.1 基本概念

1.1.1 状态码

状态码用于标识当前连接的状态,包括连接中的状态和结果状态

  1. 1XX 代表的是中间状态,此时服务端还未返回结果
  2. 2XX 代表的是成功状态,此时服务端已经收到请求并处理返回数据。
  3. 3XX 代表的是重定向,表示资源地址发生变化
  4. 4xx 代表的是请求错误,可能是地址错误也可能是参数等错误
  5. 5xx 代表的是服务端处理错误,可能是逻辑错误也可能是其他

1.1.2 常见字段

  1. host: 域名,服务定位地址
  2. connect: Keep-Alive, HTTP 1.1之后默认长连接模式,
  3. content-type: 传输数据类型
  4. content-encoding: 传输数据的压缩方式

1.1.3 端口

HTTP默认端口: 80

1.2 版本演变

版本 1.1

长连接

  • 长连接的出现优化了1.0版本每次请求都要重新进行TCP三次握手和四次回收的过程。
  • 链接的中断由两端主动发起时,才会执行四次挥手的过程
  • 长连接的出现,产生了另一个技术优化方向,管道
  • 这个时候的连接还是一个请求,一个应答而且有优先级一说,这就导致了队头阻塞问题,一个请求卡主,后面的就都不能有响应

版本 1.2

多路复用

  • 移除了串行请求,可以在一个连接中并发多个请求和回应,而不用按顺序一个一个的执行

数据流

  • 多路复用的存在支持并发多个请求,同样的支持多个响应。所以数据传输存在了一个连接里面的多个数据包可能是不同的请求响应,所以需要进行标记。

版本 1.3

HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP!

1.3 TCP

1.3.1 基本概念

  1. TCP是一个传输层协议
  2. TCP是面向连接的,可靠的,基于字节流的传输协议
    • 面向连接: 数据传输前需要先经过三次握手建立连接才能传输数据,连接是一对一的。对比UDP协议,UDP不需要建立连接,支持一对多。连接的本意也在于双向通信
    • 可靠性: 无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端.因为序号和确认号的存在,能保证服务端接收了全部数据,失败或超时的情况下会重新发送

1.3.2 TCP头

应用层数据通过连接层时会被封装成 TCP header + data 的形势,其中TCP header涉及到的就是TCP连接的一些信息,主要包括:

  1. 源端口和目标端口: 每个端口对应一个进程,源端口代表的是当前连接,随机生成。如果访问的是HTTP请求,目标端口是 80, 如果是 HTTPS 则端口为 443.
  2. 序列号: TCP传递的是字节流,每一个字节都有一个编号,序号代表的是这次发送数据的起始编号,如果是三次握手过程,则是先生成的一个随即数。它可以解决网络包的乱序问题
  3. 确认号: 服务端已接收的数据的编号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。
  4. 控制位: 行为指令
    • ACK: 应答字段,只有刚开始客户端请求发起连接时为0,其余都为1.
    • RST: 连接重置字段,该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接
    • SYN: 请求连接字段,该位为 1 时,表示客户端或服务端请求建立TCP连接
    • FIN: 断开连接字段,四次挥手断开连接时使用
  5. 窗口: TCP数据传输时有窗口控制机制,可以用于控制数据传输的效率

1.3.3 三次握手

1)、客户段发起请求

  1. 请求一般都是由客户端发起的,然后这个时候客户端一般处于 CLOSE 状态,而服务端则处于 LISTEN 状态,可以监听客户端发出的请求。
  2. 生成随机初始化信号 client_isn. 发送请求报文,此时 SYN = 1其余为0,序号值为 client_isn
  3. 客户端处于 SYN-SENT 状态

2)、服务端接收请求并发出确认报文

  1. 服务端收到客户请求回复报文携带信息如下:
    • 控制端 ASK 和 SYN 都为1,其余为0
    • 生成随即序号 server-isn且确认号为收到的 client-isn + 1
    • 携带窗口信息
  2. 服务端发出确认报文后,处于 SYN-RCVD 状态

3)、客户端确认报文

  1. 报文携带信息如下:
    • 控制端 ACK 为 1
    • 确认号为 server-isn + 1
  2. 客户端处于 ESTABLISHED 状态
  3. 服务端收到确认报文后也处于 ESTABLISHED 状态

1.3.4 为什么要经过三次握手

1)、避免历史请求初始化连接

  1. 网络的复杂环境可能会引发时序问题,比如旧的请求在新请求处理完之后服务端才收到的情况,这种情况下,客户端其实已经不再需要当前的请求。此时服务端会返回请求确认报文
  2. 客户端收到旧请求的确认报文时,判断当前请求已过期,就会发送一个 RET 请求给服务端用于终止连接。

2)、同步双方初始序列号

  1. TCP通信双方必须维护一个序列号,这个序列号是保证可传输的关键因素
  2. 两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。

1.3.5 四次挥手

客户端和服务端都可以主动断开连接,多数情况下是客户端主动断开连接,执行流程如下:

  • 发送断开连接的报文,控制位 FIN = 1, 之后客户端进入 FIN_WAIT_1 状态。这个报文的 ACT 为多少不确定,但是重点在于 FIN = 1, 它是请求断开连接的指令。
  • 服务端收到报文后会回复客户端 ACK 报文,之后服务端进入 CLOSED_WAIT 状态。
  • 等待服务端发送完数据之后,发送 FIN 报文,服务端进入LAST_ACK 状态
  • 客户端收到 FIN 报文后,回复一个 ACK 报文,之后进入 TIME_WAIT 状态
  • 服务端收到 ACK 报文后进入CLOSE状态,至此服务端完成连接的关闭流程
  • 客户端经过 2MSL 的时间之后,自动进入 CLOSE 状态,至此客户端也完成了连接的关闭。

上述过程中一共发送了四个报文,每个方向都是一个 FIN 对应一个 ACK ,所以是四次挥手。在上面过程中伴随着客户端和服务端的一些行为变化。

  1. 发送 FIN 报文即代表当前端不再发送数据,但是可以接收数据,如果双方都发送了 FIN 报文,那么有接收能力也接收不到报文
  2. 之所以是四次挥手不是三次原因在于服务端的 FIN 和 ACK 报文是不能合并到一起的,因为服务端在收到客户端的 FIN 报文时有可能没有把数据传输完。

为什么 TIME_WAIT 等待的时间是 2MSL

MSL: Maximum Segment Lifetime 报文最大生存时间。报文在网络中存活的最长时间,超过后将被抛弃。
它解决的问题是,如果服务端发送了 FIN 报文,但是没有收到客户端的 ACK 报文,这种情况下,超过一个 MSL 后服务端会重发 FIN 报文。这个等待的最长时间就是 2MSL

1.4 安全问题
  1. 明文传输,导致信息泄露
  2. 没有校验机制,信息被篡改
  3. 身份校验,无法确认访问的地址是否安全

2. HTTPS 协议

HTTPS协议其实是 HTTP + TLS , 它主要解决了HTTP协议的安全问题,所以更多的是对TLS的理解

2.1 TLS

2.1.1 基本概念

TLS 加密过程中用到的一些技术术语

2.1.2 混合加密

  1. 解决HTTP协议明文传输的最好方式就是对传输内容进行加密,TLS中使用对称加密的方式实现,双方协商相同的秘钥进行加密。
  2. TCP链接之前是明文传输的,如果通过TCP在双方之间传递秘钥任然有被拦截的风险,所以加密就变得的很鸡肋
  3. 混合加密可以先使用非对称加密的方式进行两端的协商,得到一个不需要传输的两端一致的秘钥,再进行传输时通过这个秘钥传输,那么就不会有拦截的风险了

2.1.3 摘要算法

摘要算法我感觉有些鸡肋,它可以用于检测数据的完整性。具体原理时传输的数据,先使用摘要算法获取一个[指纹],然后把明文和[指纹]一起加密再传输,接收方解密之后也进行摘要算法,然后生成的[指纹]和对方的[指纹]对比确认数据的完整性。

如果数据被解密,摘要算法不被破解的情况下,确实能防止数据被篡改。

问题如下:

  1. 明文本就会进行加密传输,要被篡改则需要获取到对称加密的秘钥,那么这个时候数据传输就不是安全的
  2. 摘要算法可以计算出数据是否被篡改,但是摘要算法也能被破解

2.1.4 数字证书

数字证书解决了公钥的可靠性问题和对方的身份识别问题

想像一个问题,如果保证客户端得到的公钥是可靠的,因为TCP三次握手的过程是明文的,需要混合加密之后协商一些对称秘钥,但是对称秘钥需要先进行非对称加密,非对称加密又需要客户端收到服务端的公钥,如何保证公钥是可靠的,不是被篡改的。

  1. 解决方式是把公钥放到数字证书中,只要证书是可靠的,公钥就是可靠的。
  2. CA的证书已事先置入到操作系统或浏览器中,不需要传输
  3. 客户端拿到服务端的数字证书后,使用CA的公钥校验服务端数字证书的真实性
2.2 HTTPS建立连接的过程

2.2.1 TCP三次握手
看HTTP中的描述

2.2.2 TLS四次握手

  1. ClientHello: 首先由客户端向服务端发起加密通信请求,也就是 ClientHello 请求。包含如下信息

    • 客户端支持的 SSL/TLS 协议版本
    • 客户端生产的随机数(Client Random),后面用于生产「会话秘钥」
    • 客户端支持的密码套件列表,如 RSA 加密算法
  2. SeverHello: 服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello。包含如下信

    • 确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信
    • 服务器生产的随机数(Server Random),后面用于生产「会话秘钥」
    • 确认的密码套件列表,如 RSA 加密算法
    • 服务器的数字证书
  3. 客户端回应:

    1. 客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性
    2. 如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:
      • 一个随机数(pre-master key)。该随机数会被服务器公钥加密
      • 生成秘钥,加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信
      • 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。
  4. 服务器的最后回应:

    1. 服务器收到客户端的第三个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。然后,向客户端发生最后的信息。
      • 加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通知
      • 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验
2.3 端口

HTTP默认端口: 443

一些问题

TCP最大连接数

  1. 最大连接数 = 客户端IP数 * 客户端端口数。所以理论值为IP最大值2的32次方 乘以 端口数最大值2的16次方,结果为2的48次方
  2. 理论和实际是有差别的,实际中存在一些限制,如下
    • 首先主要是文件描述符限制,Socket 都是文件,所以首先要通过 ulimit 配置文件描述符的数目
    • 另一个是内存限制,每个 TCP 连接都要占用一定内存,操作系统是有限的

TCP和UDP的区别

  1. UDP 不提供复杂的控制机制,利用 IP 提供面向「无连接」的通信服务
  2. UDP header 只有8个字节
  3. TCP是可靠传输,UDP不是
  4. TCP面向连接,UDP是无连接

MTU和MSS

根据网络分层的设计,应用层传递的数据向下一层层传递时,在每一层都会追加一个 header 数据,在传输层追加 TCP header, 在网络层追加 IP header, 在链路层追加 MAC header.

  • MTU: 一个网络包的最大长度,以太网中一般为 1500 字节. 也就是 IP header + TCP header + data 的最大长度。
  • MSS: 除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度

由于存在 MTU 限制,所以数据传输时存在切片的情况,使得数据的大小满足 MTU, 如果切片放在 IP 层,那么当其中的一个切片丢失时,因为IP层不具有失败重传的机制所以可能导致数据丢失。为了防止这种情况的发生,切片需要放TCP层,所以就有了 MSS 的存在,它能保证到 IP 层的数据是不需要切片的。

TCP保活机制

  1. 定义一个时间段,在这个时间段内没有任何连接活动的情况下,TCP保活机制开始起作用
  2. 每隔一个时间间隔发送一个探测报文,如果连续几个探测报文都没得到回应,则认为当前 TCP 连接已死亡。
// linux 内核默认设置
net.ipv4.tcp_keepalive_time=7200 
net.ipv4.tcp_keepalive_intvl=75  
net.ipv4.tcp_keepalive_probes=9

// tcp_keepalive_time=7200:表示保活时间是 7200 秒(2小时),也就 2 小时内如果没有任何连接相关的活动,则会启动保活机制
// tcp_keepalive_intvl=75:表示每次检测间隔 75 秒;
// tcp_keepalive_probes=9:表示检测 9 次无响应,认为对方是不可达的,从而中断本次的连接。

针对不同情况的处理:

  1. 对端程序是正常工作的。当 TCP 保活的探测报文发送给对端, 对端会正常响应,这样 TCP 保活时间会被重置,等待下一个 TCP 保活时间的到来。
  2. 对端程序崩溃并重启。当 TCP 保活的探测报文发送给对端后,对端是可以响应的,但由于没有该连接的有效信息,会产生一个 RST 报文,这样很快就会发现 TCP 连接已经被重置。
  3. 是对端程序崩溃,或对端由于其他原因导致报文不可达。当 TCP 保活的探测报文发送给对端后,石沉大海,没有响应,连续几次,达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值