Skip to main content

计网

HTTP状态码#

分类#

分类分类描述
1**信息响应,服务器收到请求,需要请求者继续执行操作
2**成功响应,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器在处理请求的过程中发生了错误

常见状态码#

  • 200 - 请求成功
  • 204 - 请求处理成功,但没有资源可返回
  • 206 - 对资源的某一部分进行请求
  • 301 - 资源被永久转移到其它 URL(永久重定向到新的 location) Moved Permanently
  • 302 - 资源临时移动(临时重定向) Found
  • 303 - See Other
  • 304 - 所请求的资源未修改
  • 307 - 临时重定向 Temporary Redirect
  • 308 - Permanent Redirect
  • 400 - 请求报文存在语法错误
  • 403 - 没有权限
  • 404 - 请求的资源不存在
  • 500 - 内部服务器错误
  • 502 - 网关错误
  • 504 - 网关超时

关于302 303 307

  • HTTP1.0 -> 302 HTTP1.1 -> 303 307
  • 客户端发送POST请求收到302状态码,由于无法向新的URI发送重复请求(需要和用户确认),会把POST请求变为GET请求
  • 302 允许各种各样的重定向,一般情况下都会实现为到 GET 的重定向,但是不能确保 POST 会重定向为 POST
  • 303 只允许任意请求到 GET 的重定向
  • 307 和 302 一样,除了不允许 POST 到 GET 的重定向

308 的定义实际上和 301 是一致的,唯一的区别在于,308 状态码不允许浏览器将原本为 POST 的请求重定向到 GET 请求上。

HTTP Method#

  • get 获取数据
  • post 新建数据
  • patch/put 更新数据
  • delete 删除数据

Get 和 Post 的区别?#

  • 缓存:get请求的数据是可以缓存的;post是不可缓存的。
  • 功能
    • get请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存。
    • post做的一般是修改和删除的工作,所以必须与数据库交互,所以不能使用缓存。
  • 传参:get传参,参数是在 url 中的;post传参,参数是在请求体中。
  • 安全性:get不安全,post较为安全:post易于防止CSRF
  • 参数长度:get参数长度有限,是较小的;post传参长度不受限制。
let params = new URLSearchParams();params.append('pid', 123);?

get 请求传参长度的误区#

误区:我们经常说 get 请求参数的大小存在限制,而 post 请求的参数大小是无限制的。

  • HTTP协议未规定GETPOST的请求长度限制

  • GET的最大长度显示是因为:浏览器和 web 服务器限制了 URL 的长度

  • 不同的浏览器和 WEB 服务器,限制的最大长度不一样

  • 要支持IE,则最大长度为2083byte,若只支持Chrome,则最大长度 8182byte

HTTP 首部#

  • HTTP 请求报文:请求方法、URIHTTP版本、HTTP首部字段
  • HTTP 响应报文:HTTP版本、状态码、HTTP首部字段

image-20211004095902398

image-20211004095950303

HTTP首部字段#

  • 首部字段名:字段值

通用首部字段#

  • Cache-Control :能够控制缓存的行为
  • Connection
    • 控制不再转发给代理的首部字段
    • 管理持久连接 Connection: Keep-Alive / close 一次 TCP 连接重复使用
  • Date:表明创建 HTTP 报文的日期和时间
  • Warning:会告知用户一些与缓存相关的问题的警告

请求首部字段#

  • Accept:告知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级
    • Accept-Charset :优先的字符集
    • Accept-Encoding:可接收的压缩算法 gzip
    • Accept-Languagezh-cn
  • Authorization:Web 认证信息
  • Host:请求的域名是什么
  • User-Agent:浏览器信息
  • If-Match If-Modified-Since If-None-Match If-Range
  • Cookie

响应首部字段#

  • ETag:资源的匹配信息
  • Location:提供重定向url
  • Server:HTTP 服务器的安装信息
  • Set-Cookie

实体首部字段#

  • 包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息

  • Content-Type: text/html

  • Keep-Alive: timeout=15, max=100

  • Allow:请求资源允许使用的方法

  • Content

    • Content-Encoding:返回数据的压缩算法,如 gzip
    • Content-Language
    • Content-Length
    • Content-Type:返回 / 发送数据的格式,如application/json
  • Expires Last-Modified

缓存相关#

Cache-Control   ExpiresLast-Modified If-Modified-SinceEtag    If-None-Match

OSI 七层模型#

  • TCP 属于传输层
  • 发送数据是封装过程 接收则是解封装

OSI 七层模型

物理层#

通过物理手段 ( 网线,光纤,无线 ) 将设备连接在一起,实现0/1电信号 (比特流) 的透明传输

数据链路层#

通过以太网协议,对0/1电信号进行分组,让双方计算机都能够识别

  • 将来自物理层的原始数据进行 MAC 地址的封装与解封装

  • 点到点传输

  • 以太网协议:规定一组电信号构成一个数据包,即

  • MAC地址:通过MAC地址确定接收的人

  • 广播:向同子网中全部计算机发送数据包,其它计算机根据数据包中接收者的 MAC地址 来判断是否接收数据包

网络层#

如果是同一个子网,我们就用广播的形式把数据传送给对方,如果不是同一个子网的,我们就会把数据发给网关,让网关进行转发

  • 路由器 数据包分组

  • 将数据链路层的数据进行 IP 地址的封装与解封装

  • 数据链路层是解决同一网络内节点之间的通信,而网络层主要解决不同子网间的通信

  • IP协议判断双方是否在同一个子网

  • 子网掩码:网络位 + 主机位 组成

  • ARP地址解析协议:通过广播接收者的IP地址来获取接收者的MAC地址

传输层#

传输层的功能就是建立端口到端口的通信,而相比之下网络层的功能是建立主机到主机的通信

  • 定义传输数据的协议和端口 TCP UDP
  • 将从下层接收的数据进行分段和传输,到达目的地址后再进行重组
  • 向用户提供可靠的、透明的、端到端的数据传输,以及差错控制和流量控制机制
  • TCP 流量控制

会话层#

会话层建立、管理和终止应用程序进程之间的会话和数据交换

表示层#

主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等

应用层#

将输入的域名url变成ip地址通信

DNS解析

终端应用

TCP & UDP#

  • TCP 是面向连接的、可靠的、基于字节流的传输层通信协议
对比UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输,使用流量控制和拥塞控制
连接个数支持一对一,一对多,多对一和多对多通信只能一对一通信
传输方式面向报文面向字节流
首部开销首部开销小,仅8字节首部最小20字节,最大60字节
适用场景适用于实时应用 ( IP电话、视频会议、直播等 )适用于要求可靠传输的应用,例如文件传输

连接方面#

可靠性#

  • TCP 是可靠传输;一旦传输过程中丢包的话会进行重传
  • UDP 是不可靠传输,但会最大努力交付

工作效率#

  • UDP 实时性高,比 TCP 工作效率高
  • 因为不需要建立连接,更不需要复杂的握手挥手以及复杂的算法,也没有 4 重传机制

是否支持多对多#

  • TCP 是点对点的
  • UDP 支持一对一,一对多,多对多

首部大小#

  • TCP 首部占 20 字节
  • UDP 首部占 8 字节,首部开销小。同样的报文内容,UDP 会比 TCP 更高效。

拥塞控制、流量控制#

  • TCP 有拥塞控制和流量控制机制,保证数据传输的安全性。
  • UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率。

三次握手四次挥手#

  • SYN(Synchronize) 同步 ACK 确认
  • ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1
  • FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位置为 1 的 TCP 段。

三次握手#

三次握手

图片

实质:客户端连接服务器指定端口 建立 TCP 连接,并同步双方的序列号和确认号,交换TCP窗口大小信息

  • 服务端调用listen系统命令,进入监听状态,等待客户端的连接。
  • 客户端向服务端发送连接请求报文。客户端会随机初始化「序号」x,并将中SYN 标志位置为1,发送SYN报文。 SYN=1 seq=x
  • 服务端收到请求报文,向 客户端 发送 连接确认报文 。服务端也随机初始化自己的「序号」 y ,其次将TCP首部的「确认应答号」字段填入 x+1,接着把 SYNACK 标志位置为 1SYN=1 ACk=1 seq=y ack=x+1
  • 客户端 收到 服务端的连接确认报文后,还要向 服务端 发出确认,「确认应答号」为 y+1,「序号」为 x+1ACK=1 seq=x+1 ack=y+1
  • 服务端 收到 客户端 的确认后,连接建立

第三次握手是可以携带数据的,前两次握手是不可以携带数据的

为什么三次

  • 三次握手才可以阻止历史重复连接的初始化(主要原因)

  • 三次握手才可以同步双方的初始序列号

  • 三次握手才可以避免资源浪费 (SYN泛洪?

  • 第一次握手:客户端发送网络包,服务端收到了。 服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

  • 第二次握手:服务端发包,客户端收到了。 客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。

  • 第三次握手:客户端发包,服务端收到了。 服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

  • 因此,需要三次握手才能确认双方的接收与发送能力是否正常

四次挥手#

四次挥手

  • 当主动方关闭连接时,会发送 FIN 报文,此时主动方的连接状态由 ESTABLISHED 变为 FIN_WAIT1。当被动方收到 FIN 报文后,内核自动回复 ACK 报文,连接状态由 ESTABLISHED 变为 CLOSE_WAIT,顾名思义,它在等待进程调用 close 函数关闭连接。当主动方接收到这个 ACK 报文后,连接状态由 FIN_WAIT1 变为 FIN_WAIT2,主动方的发送通道就关闭了。
  • 再来看被动方的发送通道是如何关闭的。当被动方进入 CLOSE_WAIT 状态时,进程的 read 函数会返回 0,这样开发人员就会有针对性地调用 close 函数,进而触发内核发送 FIN 报文,此时被动方连接的状态变为 LAST_ACK。当主动方收到这个 FIN 报文时,内核会自动回复 ACK,同时连接的状态由 FIN_WAIT2 变为 TIME_WAITLinux 系统下大约 1 分钟后 TIME_WAIT 状态的连接才会彻底关闭。而被动方收到 ACK 报文后,连接就会关闭。

图片

  • 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
  • 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSED_WAIT 状态。
  • 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  • 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
  • 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
  • 服务器收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
  • 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。

MSL 是 Maximum Segment Lifetime,报文最大生存时间

为什么需要三次握手,四次挥手呢?

  • 3次握手的作用就是双方都能明确自己和对方的收、发能力是正常的,三次连接是保证可靠性的最小握手次数。
  • 4次挥手呐,TCP的全双工通信断开连接,需要双方的都确认断开。当客户端确认自己没有数据要传给服务器时,并不能保证服务器也没有数据要发送了。前两次挥手是客户端和服务器对连接断开的确认,第三次服务器会将剩下的数据发给客户端。

TCP拓展#

  • 粘包
  • TCP可靠传输:超时重传
  • TCP滑动窗口:控制字节流存放大小?
  • TCP流量控制:控制发送方发送速率,保证接收方来得及
  • TCP拥塞控制:网络拥塞时,控制重传速率

DNS解析#

DNS域名解析过程1

域名解析#

www.qq.com..  -> .com -> qq.com -> www.qq.com跟域名  -> 顶级域名  -> 二级域名  -> 三级域名

多级缓存#

  • 缓存命中:浏览器缓存 => 操作系统缓存 => LDNS 本地区域名服务器缓存(学校机房 / ISP
  • LDNS => 根域名服务器 根域名服务器返回给 LDNS 一个所查询的主域名服务器 gTLD 地址
  • LDNS => gTLD 发起请求 返回域名对应的 Name Server 域名服务器地址
  • LDNS => Name Server 查询请求域名的对应IP地址 返回对应IP以及TTL
  • LDNS 根据返回的TTL对IP进行缓存 并将结果返回给用户
  • TTL: time to live 域名缓存的最长时间

解析优化#

原因:DNS解析的过程中浏览器什么都不会做直到DNS查询完毕

使用TTL:TTL: time to live 域名缓存的最长时间

负载均衡:在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的,可以根据每台机器的负载量或该机器离用户地理位置的距离入手

HTTPS & HTTP#

HTTP:无状态(stateless)协议。HTTP 协议自身不对请求和响应之间的通信状态进行保存。即协议对于发送过的请求或响应都不做持久化处理

区别#

  • HTTP:无状态无连接,而且是明文传输,不安全 80
  • HTTPS:传输内容加密,身份验证,保证数据完整性 HTTP + SSL/TLS 443 在HTTP 与 TCP层之间加入了 SSL/TLS 协议

HTTP 的不足#

  • 通信使用明文,内容可能会被窃听 -> 通信加密 数据加密
  • 不验证通信方的身份,因此有可能遭遇伪装 -> SSL HTTPS 数字证书
  • 无法证明报文的完整性,所以有可能已遭篡改 -> 中间人攻击 MD5 数字签名

数字证书#

  • 解决通信身份可能被伪装问题
  • 服务器运营人员向第三方证书机构提交 CA 公钥、组织信息、域名等信息进行申请认证
  • 数字证书机构通过线上线下等手段去验证所提供的信息是否合法。合法的话会向申请者颁发证书(包含 CA 公钥、证书机构和所有者组织信息、证书有效时间、序列号等信息,还包含一个签名(使用散列函数计算公开明文的消息摘要并通过 CA 的私钥进行加密 => 签名
  • 客户端向目标服务器发起请求时会返回相应的证书文件
  • 客户端读取证书中信息,进行相同的散列函数计算得到消息摘要。通过 CA 中的公钥解密签名数据,对比证书的消息摘要是否一致来判断是否合法

完整性检测 - 数字签名#

  • 将一段文本通过hash函数生成消息摘要,再通过客户端的私钥进行加密生成数字签名
  • 服务器收到数字签名后先用公钥进行解密 得到消息摘要
    • 然后对收到的原文也进行hash生成消息摘要
    • 比较前后两次消息摘要 如果相同 则证明完整没有被篡改

HTTPS 实现原理#

HTTP + 加密 + 认证 + 完整性保护 = HTTPS

  • 过程

    • 客户端发送消息给服务器(包含可用的加密算法和压缩算法
    • 服务器返回消息给客户端(包含选用的加密和压缩算法以及数字证书认证机构 CA 签发的证书(包含公钥 + 证书所应用的域名范围
    • 客户端去验证公钥证书 是否合法
    • 客户端使用伪随机数生成传输信息所用的对称密钥,然后通过证书的公钥去传输对称密钥
    • 服务端接收到信息后,用自己的私钥去解密来获得对称密钥
    • 服务端使用对称密钥与客户端进行通信(此时双方都已经拥有了对称密钥
  • SSL 公钥加密的算法

    • 对称加密的问题:密钥分发的问题 安全性问题
  • HTTPS 采用 共享密钥(对称加密) 和 公开密钥(非对称加密)两者混用的加密机制

    • 非对称:交换对称密钥。通信建立前
    • 对称:信息交换。通信过程中

HTTP 版本#

  • HTTP/0.9:只能进行get请求,发送纯文本
  • HTTP/1.0:添加了POST、HEAD、OPTION、PUT、DELETE
  • HTTP/1.1:
    • 默认支持了长连接keep-alive:旨在建立 1TCP 连接后进行多次请求和响应的交互 Keep-Alive: timeout=5, max=100
    • 管线化:不用等待响应亦可直接发送下一个请求,就能够做到同时并行发送多个请求
    • 虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了 Cookie 技术(通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态
    • 增加了host 域,而且节约带宽?
  • HTTP/2:
    • 多路复用:让所有的通信都在一个 TCP 连接上完成,实现了请求的并发
    • 头部压缩:利用 HPACK 算法压缩头部的User-Agent Cookie Accept Server Rabge等字段
    • 服务器推送:使得服务器可以预测客户端需要的资源,主动推送到客户端

关于HTTP的队头阻塞问题

  • HTTP/1.0 每次请求都会建立一个TCP连接 请求结束后立即断开连接
  • HTTP/1.1 每一个连接都是长连接。对于同一个TCP连接可以发送多个HTTP/1.1 请求。
    • 不必等前一个返回就可以发送下一个 --> 解决了HTTP/1.0 中客户端的队头阻塞 --> Pipline
    • 但是HTTP/1.1 要求服务端返回响应 按照请求发送顺序返回 --> 1.0 的服务端的队头阻塞
  • HTTP/2.0
    • 二进制封帧
      • HTTP/1.1数据包是文本格式的, 而 HTTP/2 的数据包是二进制格式
      • 采用帧的传输方式可以将请求和响应的数据分割的更小
    • 多路复用
      • HTTP/1.1 并发多个请求需要多个TCP链接,且单个域名有6-8个TCP链接请求限制
      • 同一域名下所有通信在单个TCP链接下完成,且这个链接可以并行请求和响应 互不干扰

使用长连接之后,客户端、服务端怎么知道本次传输结束呢?

  • 判断传输数据是否达到了Content-Length 指示的大小
  • 动态生成的文件没有 Content-Length ,它是分块传输chunked,这时候就要根据 chunked 编码来判断,chunked 编码的数据在最后有一个空 chunked 块,表明本次传输数据结束

一个 tcp 连接能发几个 http 请求?#

如果是 HTTP 1.0 版本协议,一般情况下,不支持长连接,因此在每次请求发送完毕之后,TCP 连接即会断开,因此一个 TCP 发送一个 HTTP 请求,但是有一种情况可以将一条 TCP 连接保持在活跃状态,那就是通过 Connection 和 Keep-Alive 首部,在请求头带上 Connection: Keep-Alive,并且可以通过 Keep-Alive 通用首部中指定的,用逗号分隔的选项调节 keep-alive 的行为,如果客户端和服务端都支持,那么其实也可以发送多条,不过此方式也有限制,可以关注《HTTP 权威指南》4.5.5 节对于 Keep-Alive 连接的限制和规则。

而如果是 HTTP 1.1 版本协议,支持了长连接,因此只要 TCP 连接不断开,便可以一直发送 HTTP 请求,持续不断,没有上限; 同样,如果是 HTTP 2.0 版本协议,支持多用复用,一个 TCP 连接是可以并发多个 HTTP 请求的,同样也是支持长连接,因此只要不断开 TCP 的连接,HTTP 请求数也是可以没有上限地持续发送