计算机网络和http协议知识点梳理

581 阅读11分钟

概述

计算机网络通过分层的方式将网络传输中的各个功能模块化处理,然后相邻层之间通过接口连接,两个通信实体的同层之间使用协议通信,对每层的实现细节进行封装。

分层模型主要包括osi模型(七层)和tcp/ip模型(四层)两种,其中前面一种过于理想化,具体实现比较低效,后一种链路层描述过于简略,因此实际学习我们按照改进过的五层模型。

image

本文是对相关知识点的梳理,详见这里

五层模型

在完整的网络传输过程中,高层向低层传递信息,每层(不包括物理层)都会添加一个header,header中包含着改成所需要的信息,这个过程从应用层开始,我们以访问一个web页面为例:

  • 应用层 应用层生产一个message,即请求浏览器发起一个下载web页面的请求,这个消息随后被发往传输层。
  • 传输层 添加tcp或udp的hader,包含数据源和目的地址的端口地址。另外的信息比如tcp使用的packet 序列号也会添加到header。如果使用的是tcp,则会生成一个Segment,如果使用的udp,则生成Datagram,然后被发往网络层。
  • 网络层 添加了包含源和目的的ip地址的header,生成一个packet,然后发往数据链路层
  • 数据链路层 添加包含当前和下一跳mac地址的header,生成一个frame,发往物理层传输bit

接收方,包括中间设备和最终目的地址,会从下到上依次剥离并解析消息头,如果只是对具体消息不关心的中间设备,在获得自己需要的消息后,比如网络层设备,会处理完网络层协议后,重新添加自己的消息头,传递给下一个设备。

应用层

包含各种应用直接使用的协议,比如

  • DHCP 当客户端检测有网络时会自动向服务器请求一个ip,服务器一般运行在路由器中
  • DNS 可以通过域名获取ip。一个网络需要ip(不能是domain或host)才能生成一个packet

传输层

从应用层获取数据,然后会将每个运行的进程添加一个端口号,并在获取的数据上添加tcp或udp header。

tcp协议关注一下报文的几个字段和连接管理

网络层

当发送数据时,本层会添加包含源ip和目的ip的头部,然后发送到数据链路层。

当接收数据时,对于host,如果接收的数据目的ip是本机地址,则发送到传输层.对于路由器,会根据ip进行路由选择发送给目标host或者路由器,具体的转发要通过arp协议获取对应mac地址。

数据链路层

数据链路层用于在单个网络内部的设备中传输信息。 当发送数据时,将包含源和目标mac地址的header封装到从网络层接收到的数据包中,创建frame发送到物理层。

当接收数据时,对于主机,如果数据中包含本机的mac地址则传到网络层进一步处理;

对于中继设备(比如网桥和交换机),这些设备的每个端口都是一个碰撞域(冲突域,也叫网段,每个碰撞域中的主机用线或者物理层中继设备连接),一个碰撞域可以由多个设备相连,它们可以直接通信而不需要借助数据链路层设备转发。因此如果接收到的源mac和目的mac在同一个碰撞域,则直接丢弃(因为它们可以直接通信),否则转发到目标碰撞域(中继设备的另一个端口)。

物理层

用网线或者无线传输frame中的bit流,本层的中继设备(中继器和集线器)只用来延长线路。

http

http是一种无状态请求响应协议,通过可靠的传输层连接交换信息,client指的是建立连接的程序,server是接受http连接的程序。

除了c/s外,还有几个中介(Intermediaries)

  • proxy 是一个信息转发agent,作为中介去代替user agent发出请求,可以用来缓存或隐蔽个人信息。
  • gateway 即reverse proxy ,是origin server端的代理,将收到的请求传递给server,可以用来封装遗留的或者不信任的服务、通过缓存提高服务器性能,以及负载均衡。
  • tunnel 在两个连接中进行盲转发,不会修改信息的任何内容,比如在tls中通过防火墙

版本变化

第一个版本的http协议是http/0.9,只有一个方法get,用来获取html文档。

1996年的http/1.0通过引入header和新的method对其进行了扩展。

第二年http/1.1发布,规定了我们使用的主要语法和语义,之后的版本都是对该版本的补充。

2015年5月HTTP/2发布,具体见后文。

http/1.1升级

http/1.1可以使用upgrade请求头来将已建立的连接升级未其他协议(比如websocket或http/2.0),注意这种机制只能在http/1.1使用,不能在2.0及以上使用。 协议升级总是由浏览器发起,一个升级的请求要另外携带两个header,Connection: Upgrade表示这是一个升级请求的连接,Upgrade: protocols表示想要升级为的协议

GET /index.html HTTP/1.1
Host: www.example.com
Connection: upgrade
Upgrade: example/1, foo/2

服务器一旦升级成功,就会返回101的status code,此时可以使用新协议通信。

连接管理

包含多个连接模型,包括短链接、持久连接和pipelining。

最初的每个http连接需要创建一个tcp连接,一旦收到响应就会关闭连接。 http1.1引入两个新的模式,持久连接会保持成功的连接,复用tcp连接,http pipelining不需要等待响应而直接发送多个请求。

以上三个模式第一个浪费性能,第三种实践中具有局限性,默认关闭。

CORS

Cross-Origin Resource Sharing (CORS)基于http header的机制。
除了简单的跨域请求之外,浏览器需要向目标服务器发一个option方法的preflight来检查是否允许对应请求,这个preflight中浏览器发送header来表明实际的请求中的方法和header.

某些请求不会触发preflight,这类请求被称为简单请求 这类请求满足以下条件

  • 使用以下方法 get post head
  • 只能用部分header
  • Content-Type只能取值 text/plain multipart/form-data application/x-www-form-urlencoded
  • XMLHttpRequestUpload对象没有注册事件监听,但是可以通过XMLHttpRequest.upload 访问。
  • 请求中没使用ReadableStream对象

authentication

相关状态码

  • 401 Unauthorized 缺少请求目标资源的身份认证信息
  • 403 Forbidden 权限不足

相关header

  • Authorization

缓存

一次请求的响应内容可以在origin server之外的节点保存,当对应请求再次发生时,就会直接从缓存中读取。

当我们使用缓存时要注意两点,一点是决定是否要缓存,一点是缓存的内容何时被更新。这两点的控制要通过http header,最终是否用的缓存要根据状态。

工作原理

验证缓存是否可用需要借助验证器,包括eTag和last-Modified(etag优先级高),如果没有则不会缓存。

常用的缓存header是cache-control,之前使用的expires和pragma,这里不推荐使用。

主要流程包括

  1. 当浏览首次get请求时,浏览器没有对应缓存,origin server会返回资源和相关header。如果cache-control值不是no-store,且含有验证器,则在浏览器端缓存。
  2. 当浏览器再次发起相应请求。 如果没有缓存,则重复第一步 如果有缓存 如果是一次需要验证的请求,比如max-age过期或者cache-control:no-cache,则使用etag或last-modified进行验证,如果验证通过则返回304 Not Modified,使用缓存的信息,结束本次请求,如果验证不通过,则返回200 OK新的响应。 否则直接使用缓存,返回200 OK (from cache)

cookies

http本身是无状态协议,服务端可以通过set-cookie指定内容保存在浏览器,下一次访问被携带发回服务器。
同一个响应可以包含多个set-cookie从而设置多个cookie,多个参数用分号隔离,比如

Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly

其中的参数含义为

  • = 一个表示cookie的键值对,键名可以包含两种前缀
    • __Secure- 前缀,要和secure参数一起设置,且用于https页面
    • __Host- 前缀,与secure参数一起设置,用于https页面,不能设置domain,path值为'/'
  • Expires= 失效时间
  • Max-Age= 指定秒数后失效,优先级高于expires
  • Domain= 指定域名下的请求携带cookies,默认当前域名,如果显式指定则包含各个子域,
  • Path= 指定路径下的请求才会携带cookies
  • Secure 在https使用
  • HttpOnly 设置后不能使用js获取

重定向

url重定向,也就是url转发。可以用来给一个页面、一个网站或应用多个url。 重定向由服务器发送特定状态码触发,浏览器接收到相关响应后会立即请求新的url,可以用在使用多个域名或强制https时。

永久重定向,表示原url不被使用,会被搜索引擎更新为新的url

  • 301 Moved Permanently 所有请求方法会在重定向时采用get;
  • 308 Permanent Redirect时重定向的请求不会发生变化。

临时重定向,不会被搜索引擎更新

  • 302 Found 所有请求方法在重定向时有可能使用get;
  • 303 See Other 所有方法变成get,body丢失;
  • 307 Temporary Redirect 重定向时不会发生变化。

特殊重定向

  • 300 Multiple Choice用于内容协商提供多个可使用的链接
  • 304 Not Modified 用于验证缓存时表示缓存依然可用

其他重定向方法 html

<meta http-equiv="Refresh" content="0; URL=http://example.com/" />

js

window.location = "http://example.com/";

优先级从高到低为,http-meta-js

响应code

这里

https和tls

https即http over tls,http指的是http over tcp. 避免窃听(eavesdropping),篡改(tampering), and 消息伪造(message forgery)

tls协议中会利用非对称加密将后续对称加密使用的密钥发送给服务端。

为了避免首次通信时存在中间人攻击,引入ca证书,ca证书标记一个域名,ca证书也是非对称加密,私钥和证书在服务端,服务端利用ca私钥将证书和相关数据(比如对称加密使用的密钥)发送给客户端,客户端可以利用浏览器内置公钥对证书验证,以防止中间人攻击。

tls握手发生在tcp握手后,也包含三次握手。

tls握手

  • 客户端明文发送一个ClientHello消息,包含协议版本、可选的加密套件、random nonce等(使用一次的随机字符串,用于生成shared key)
  • 服务端计算出sharedkey,回复serverHello,包含选定的加密套件,证书,随机数,并用证书对应的私钥加密
  • 客户端对收到的证书验证,用证书公钥解密后根据相关参数算出sharedkey

此时握手结束,client和server获取了record层保护数据传输所用的shared key,除非特别指定,否则在发送Finished之前不要发送应用数据。

http2

http1存在的问题

  • 需要多个连接才能实现并发和缩短延迟(每个tcp连接同时只能处理一个http请求)
  • header 重复且冗长,从而导致不必要的网络流量
  • 不支持资源优先级,导致连接利用率低下

http2的解决方式

http2通过在应用层引入二进制帧层来解决以上问题,通过对http传输信息修改编码,从1.x版本的纯文本,改为更小的的二进制帧。

具体

http3

具体