网络模型

同一台设备上的进程间通信,有很多种方式,比如有管道、消息队列、共享内存、信号等方式

不同设备上的进程间通信,需要网络通信,而设备是多样性的,协商出了一套通用的网络协议

  • TCP/IP网络模型

    • 应用层
      • 最上层的,也是我们能直接接触到的,应用就把应用数据传给下一层,就是传输层
      • 应用层为用户提供应用功能,比如 HTTP、FTP等
    • 传输层
      • 传输层会有两个传输协议,分别是 TCP 和 UDP
        • TCP:大部分应用使用的正是 TCP 传输层协议,比如HTTP。TCP有流量控制、超时重传、拥塞控制等,为保证数据包能可靠地传输给对方
        • UDP:只负责发送数据包,不保证数据包是否能抵达对方,它实时性相对更好,传输效率也高
      • 应用需要传输的数据可能会非常大,当传输层的数据包大小超过 MSS(TCP 最大报文段长度),将数据包分块,这样即使中途有一个分块丢失或损坏了,只需要重新发送这一个分块
        • MTU:一个网络包最大长度,以太网中一般为 1500 字节。
        • MSS:除去 IP 和 TCP 头部后,一个网络包所能容纳的 TCP 数据的最大长度。
      • 传输层负责把数据包传给应用,但一台设备上会有很多应用接收或者传输数据,用编号将应用区分开来,这个编号是端口
        • 80 端口通常是 Web 服务器用的,22 端口通常是远程登录服务器用的
        • 对于浏览器(客户端)中的每个标签栏都是一个独立的进程,操作系统会为这些进程分配临时的端口号
    • 网络层
      • 传输层协议处理太多的事情,只需要服务好应用即可;而实际的传输功能就交给下一层,也就网络层,负责将数据从一个设备传输到另一个设备
      • IP 协议将传输层的报文作为数据部分,再加上 IP 包头组装成 IP 报文;如果 IP 报文大小超过 MTU(以太网中一般为 1500 字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文
      • IP 地址给设备进行编号
      • IPv4 协议, IP 地址共 32 位,分成了四段(比如192.168.100.1),每段是8位
      • 将 IP 地址分成两种意义:
        • 网络号,负责标识该 IP 地址是属于哪个「子网」的;
        • 主机号,负责标识同一「子网」下的不同主机
      • 配合子网掩码才能算出 IP 地址 的网络号和主机号
        • 比如 10.100.122.0/24,后面的/24表示就是 255.255.255.0 子网掩码,255.255.255.0 二进制是「11111111-11111111-11111111-00000000」
        • 10.100.122.2 和 255.255.255.0 进行按位与运算,可得到网络号
        • 255.255.255.0 取反后与IP地址进行进行按位与运算,可得到主机号
      • 寻址过程中,先匹配相同的网络号(表示要找到同一个子网),才会去找对应的主机
      • IP协议除寻址能力, IP 协议有另一个重要的能力是路由
        • 形成很多条网络的路径,因此当数据包到达一个网络节点,就需要通过路由算法决定下一步走哪条路径
      • IP 协议的寻址作用是告诉我们去往下一个目的地该朝哪个方向走,路由则是根据「下一个目的地」选择路径。寻址更像在导航,路由更像在操作方向盘
    • 网络接口层
      • 生成了 IP 头部之后,要交给网络接口层在 IP 头部前面加上 MAC 头部,并封装成数据帧(Data frame)发送到网络上
      • 以太网就一种「局域网」内,把附近的设备连接起来,使它们之间进行通讯技术
      • 必须采用**相匹配**的方式才能在以太网中将包发往目的地,而 MAC 头部就是干这个用的
    • 网络接口层的传输单位是帧(frame),IP 层的传输单位是包(packet),TCP 层的传输单位是段(segment),HTTP 的传输单位则是消息或报文(message)。可以统称为数据包
  • 网站与网页之间路径

    • 解析URL

      • 浏览器做的第一步工作就是要对 URL 进行解析,没有路径名时,就代表访问根目录下事先设置的默认文件,也就是 /index.html 或者 /default.html 这些文件
      • 组成:协议+//+web服务器+数据源路径
    • 查询IP地址

      • 浏览器解析 URL 并生成 HTTP 消息后,委托操作系统将消息发送给 Web 服务器
      • DNS 中的域名都是用句点来分隔的,比如 www.server.com,这里的句点代表了不同层次之间的界限,越靠右的位置表示其层级越高
      • 域名最后还有一个点,比如 www.server.com.,这个最后的一个点代表根域名
      • 根域的 DNS 服务器信息保存在互联网中所有的 DNS 服务器中
      • 域名的层级关系类似一个树状结构:
        • 根 DNS 服务器(.)
        • 顶级域 DNS 服务器(.com)
        • 权威 DNS 服务器(server.com)
      • 域名解析工作流程
        1. 客户端发出一个 DNS 请求,问 www.server.com 的 IP 是啥,并发本地 DNS 服务器
        2. 本地域名服务器收到客户端的请求后,如果**缓存**里的表格能找到 www.server.com,则它直接返回 IP 地址。如果没有,本地 DNS 会去问它的根域名服务器
        3. 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,说:“www.server.com 这个域名归 .com 区域管理”,我给你 .com 顶级域名服务器地址给你
        4. 这样反复,直到本地DNS问到IP地址
        5. 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接
    • 协议栈

      • 获取到 IP 后,可以把 HTTP 的传输工作交给操作系统中的协议栈
      • 应用程序(浏览器)调用 Socket 库,委托协议栈工作。
        • 上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,这两个传输协议会接受应用层的委托执行收发数据的操作。
        • 下一半是用 IP 协议控制网络包收发操作,互联网传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由 IP 负责的
      • 此外 IP 中还包括 ICMP 协议和 ARP 协议
        • ICMP 用于告知网络包传送过程中产生的错误以及各种控制信息
        • ARP 用于根据 IP 地址查询相应的以太网 MAC 地址
    • 可靠传输TCP

      • 基本字段

        • 源端口号和目标端口号是不可少的,数据就知道应该发给哪个应用
        • 有包的序号,这个是为了解决包乱序
        • 确认号,目的是确认发出去对方是否有收到。如果没有收到就应该重新发送,直到送达,这个是为了解决丢包的问题
        • 状态位,例如 SYN 是发起一个连接,ACK 是回复,RST 是重新连接,FIN 是结束连接等。TCP 是面向连接的,因而双方要维护连接的状态
        • 窗口大小,TCP 要做流量控制,通信双方各声明一个窗口(缓存大小),标识自己当前能够的处理能力
        • 拥塞控制,也即控制发送的速度
      • 三次握手

        • HTTP 传输数据之前,首先需要 TCP 建立连接,TCP 连接的建立,通常称为三次握手
        1. 客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态
        2. 客户端主动发起连接 SYN
        3. 服务端收到发起的连接,返回 SYN,并且 ACK 客户端的 SYN
        4. 客户端收到服务端发送的 SYN 和 ACK 之后,发送对 SYN 确认的 ACK
        5. 服务端收到 ACK 之后,连接成功
      • TCP 协议里面会有两个端口

        • 浏览器监听的端口(通常是随机生成的),
        • Web 服务器监听的端口(HTTP 默认端口号是 80, HTTPS 默认端口号是 443)
    • 远程定位IP

      • IP 协议里面需要有源地址 IP 和 目标地址 IP:
      • 源地址IP:客户端输出的 IP 地址;
      • 目标地址:通过 DNS 域名解析得到的 Web 服务器 IP
      • 存在多个网卡时,填写源地址 IP 时,判断到底哪个地址

        • 据路由表规则,来判断哪一个网卡作为源地址 IP
        1. 目标地址进行子网掩码运算,进行网卡匹配
        2. 若其他无法匹配,进行默认网关0.0.0.0,并且后续就把包发给路由器
    • 两点传输MAC

      • MAC 包头里需要发送方 MAC 地址和接收方目标 MAC 地址,用于两点之间的传输
      • 发送方的 MAC 地址获取就比较简单了,MAC 地址是在网卡生产时写入到 ROM 里
      • 接收方的 MAC 地址就有点复杂,明确对方的IP地址,ARP 协议在以太网中以广播的形式得 MAC 地址
    • 交换机

      • 交换机的设计是将网络包原样转发到目的地,工作在 MAC 层,称为二层网络设备
      • 交换机的 MAC 地址表主要包含两个信息:
        • 一个是设备的 MAC 地址,
        • 另一个是该设备连接在交换机的哪个端口上
      • 交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口
        • 举例:收到的包的接收方 MAC 地址为 00-02-B3-1C-9C-F9,查表中的匹配,根据端口列的信息,知这个地址位于 0 号端口上,通过交换电路将包发送到相应的端口
        • 地址表中找不到指定的 MAC 地址:
          • 将包转发到除了源端口之外的所有端口上,无论该设备连接在哪个端口上都能收到这个包
          • 以太网的设计本来就是将包发送到整个网络的,然后只有相应的接收者才接收包,而其他设备则会忽略这个包
    • 路由器

      • 基于 IP 设计的,俗称三层网络设备,路由器的各个端口都具有 MAC 地址和 IP 地址
      • 端口具有 MAC 地址,因此能够成为以太网的发送方和接收方;同时还具有 IP 地址
      • 包的发送操作。需要根据路由表的网关列判断对方的地址。
        • 如果网关是一个 IP 地址,则这个IP 地址就是我们要转发到的目标地址,还未抵达终点,还需继续需要路由器转发。
        • 如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址,也是就终于找到 IP 包头里的目标地址了,说明已抵达终点。
    • 在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输

  • HTTP

    • 基本概念

      • HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」

      • 状态码:

        1xx 类属于提示信息,协议处理中的一种中间状态,实际用到得少。

        2xx 类表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。

        • 「200 OK」是最常见的成功状态码,表示一切正常
        • 「204 No Content」与 200 OK 基本相同,但响应头没有 body 数据。
        • 「206 Partial Content」是应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。

        3xx 类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送获取资源,也就重定向。

        • 「301 Moved Permanently」永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
        • 「302 Found」表示临时重定向,说明请求资源还在,但暂时需要用另一个 URL 来访问。

        301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。

        • 「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也是告诉客户端可以继续使用缓存资源,用于缓存控制。

        4xx 类状态码表示客户端发送的报文有误,服务器无法处理,也是错误码的含义。

        • 「400 Bad Request」客户端请求的报文有错误,但只是个笼统的错误。
        • 「403 Forbidden」服务器禁止访问资源,并不是客户端的请求出错。
        • 「404 Not Found」请求的资源在服务器上不存在或未找到,所以无法提供给客户端。

        5xx 类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。

        • 「500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
        • 「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
        • 「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
        • 「503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思。
      • 常见字段

        • Host :客户端发送请求时,用来指定服务器的域名
        • Content-Length :服务器在返回数据时,会有 Content-Length 字段,表明本次回应的数据长度
          • 使用了 TCP 传输协议,就会存在一个“粘包”的问题,HTTP 协议通过设置回车符、换行符作为 HTTP header 的边界,通过 Content-Length 字段作为 HTTP body 的边界,这两个方式都是为了解决“粘包”的问题
        • Connection:用于客户端要求服务器使用「HTTP 长连接」机制 长连接的特点:只要任意一端没有明确提出断开连接,保持 TCP 连接状态
        • Content-Type :用于服务器回应时,告诉客户端,本次数据是什么格式 客户端请求的时候,使用 Accept 字段声明自己可以接受哪些数据格式
        • Content-Encoding :数据的压缩方法。表示服务器返回数据使用什么压缩格式
    • GET和POST

      • GET 的语义是请求获取指定的资源。GET 方法是安全、幂等、可被缓存的
      • POST 的语义是根据请求负荷(报文主体)对指定的资源做出处理,具体的处理方式视资源类型而不同。POST 不安全,不幂等,(大部分实现)不可缓存
      • 安全和幂等
        • 「安全」是指请求方法不会「破坏」服务器上的资源
        • 「幂等」是多次执行相同的操作,结果都是「相同」的
      • 实际过程中
        • 可以用 GET 方法实现新增或删除数据的请求,这样实现的 GET 方法自然就不是安全和幂等。
        • 可以用 POST 方法实现查询数据的请求,这样实现的 POST 方法自然就是安全和幂等。
    • HTTP缓存

      • 强缓存:只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,决定是否使用缓存的主动性在于浏览器这边

      • 资源在客户端缓存的有效期:

        • Cache-Control, 是一个相对时间;
        • Expires,是一个绝对时间
      • 流程如下:

        • 浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control,Cache-Control 中设置过期时间大小
        • 浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小,来计算出该资源是否过期,如果没有,则使用该缓存,否则重新请求服务器
        • 服务器再次收到请求后,会再次更新 Response 头部的 Cache-Control
      • 协商缓存

        • 与服务端协商之后,通过协商结果来判断是否使用本地缓存
        • 两种实现
        1. 响应头部中的 Last-Modified:标示这个响应资源的最后修改时间
        2. 响应头部中 Etag:唯一标识响应资源
      • 使ETag 字段协商缓存过程:

        • 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 ETag 唯一标识

        • 当浏览器再次请求访问服务器中的该资源时,首先会先检查强制缓存是否过期:

          • 如果没有过期,则直接使用本地缓存;
          • 如果缓存过期了,会在 Request 头部加上 If-None-Match 字段,该字段的值就是 ETag 唯一标识;
        • 服务器再次收到请求后,

          根请求中的 If-None-Match 值与当前请求的资源生成的唯一标识进行比较:

          • 如果值相等,则返回 304 Not Modified,不会返回资源;
          • 如果不相等,则返回 200 状态码和返回资源,并在 Response 头部加上新的 ETag 唯一标识;
        • 如果浏览器收到 304 的请求响应状态码,则会从本地缓存中加载资源,否则更新资源

    • 协商缓存这两个字段都需要配合强制缓存中 Cache-Control 字段来使用,只有在未能命中强制缓存的时候,才能发起带有协商缓存字段的请求

  • HTTP特性与HTTPS

    • HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输
    • HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输
    • HTTP 默认端口号是 80,HTTPS 默认端口号是 443
    • HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的

    HTTPS:

    • 解决的问题:

      • 窃听风险,通信链路上可以获取通信内容
      • 篡改风险,强制植入垃圾广告
      • 冒充风险,冒充淘宝网站
    • 如何解决:

      • 混合加密方式实现信息的保密性
      • 摘要算法方式来实现完整性,生成独一无二指纹,校验数据完整性,防止篡改
      • 服务器公钥放入到数字证书,解决了冒充的风险
    • 细节-混合加密

      • HTTPS 采用的是对称加密和非对称加密结合「混合加密」方式:
        • 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
        • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据
    • 细节-摘要算法和数字签名

      • 保证传输内容不被篡改,需对内容计算出一个「指纹」,然后同内容一起传输 对方收到后,先是对内容也计算出一个「指纹」,然后跟发送方发送的「指纹」做一个比较。 如果「指纹」相同,说明内容没有被篡改,否则就可以判断出内容被篡改了
      • 保证内容不篡改,但不能保证「内容 + 哈希值」不会被中间人替换
        • 对内容的哈希值加密,通过「私钥加密,公钥解密」的方式,来确认消息的身份
        • 私钥是由服务端保管,然后服务端会向客户端颁发对应的公钥。如果客户端收到的信息,能被公钥解密,就说明该消息是由服务器发送的
        • 理解:只换其中一个,就验证出现错误;两个都换,就公钥无法验证
    • 细节-数字证书

      • CA (数字证书认证机构),将服务器公钥放在CA中(CA私钥锁,CA公钥OS默认),只要CA公钥打开的,公钥就是可信的
      • 理解:公钥验证,若公钥及前面都变化,依旧出现问题,故公钥放到CA存

      CA 签发证书的过程:

      • 首先 CA 把持有者的公钥、用途、颁发者等信息打成包,对这些信息进行 Hash 计算,得到一个 Hash 值
      • 然后 CA 用自己的私钥将该 Hash 值加密,生成 Certificate Signature
      • 最后将 Certificate Signature 添加在文件证书上

      客户端校验服务端的数字证书的过程:

      • 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
      • 通常操作系统集成了 CA 的公钥,浏览器收到证书后使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2 ;
      • 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信

    HTTP特性

    • HTTP/1.1优点
      • 用header+body,易于理解
      • 从看新闻、刷贴吧到购物、理财、吃鸡,HTTP 的应用,天然具有跨平台的优越
      • HTTP 协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求没有被固定死,都允许开发人员自定义和扩充
    • HTTP/1.1缺点
      • 无状态双刃,Cookie 通过请求和响应报文中写入 Cookie 信息来控制客户端的状态
      • 明文传输,信息暴露。比如 Wireshark 抓包都可以直接肉眼查看
      • 比较严重的缺点就是不安全
    • HTTP1.1性能好处
      • 使用长连接改善 HTTP/1.0 短连接造成的性能开销
      • 支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间
    • HTTP1.1性能缺陷
      • 请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大
      • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多
      • 请求只能从客户端开始,服务器只能被动响应
      • 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞
    • HTTP2性能好处
      • HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,协议会帮你消除重复的部分
      • 而是全面采用了二进制格式,头信息和数据体都是二进制,并且统称为帧(frame)
      • HTTP/2 就很牛逼了,引出了 Stream 概念,多个 Stream 复用在一条 TCP 连接
      • HTTP/2 服务端不再是被动地响应,可以主动向客户端发送消息
    • HTTP3性能好处
      • 通过连接 ID 来标记通信的两个端点,连接迁移快
      • QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响,因此不存在队头阻塞问题。
      • HTTP/3 的 QUIC 协议并不是与 TLS 分层,而是 QUIC 内部包含了 TLS,它在自己的帧会携带 TLS 里的“记录”,再加上 QUIC 使用的是 TLS/1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商更快的连接建立

IP

  • 网络层的主要作用是:实现主机与主机之间的通信,也叫点对点(end to end)通信 IP 在 TCP/IP 参考模型中处于第三层,也就是网络层

  • IP 地址是以网卡分配。像服务器、路由器等设备都是有 2 个以上的网卡

  • 分类地址

    • 广播地址用于在同一个链路中相互连接的主机之间发送数据包 当主机号全为 1 时,就表示该网络的广播地址; 例如把 172.20.0.0/16 形成广播地址:10101100.00010100.11111111.11111111

    • 广播地址

      • 在本网络内广播的叫做本地广播。例如网络地址为 192.168.0.0/24 的情况下,广播地址是 192.168.0.255 。因为这个广播地址的 IP 包会被路由器屏蔽,所以不会到达 192.168.0.0/24 以外的其他链路上
      • 在不同网络之间的广播叫做直接广播。例如网络地址为 192.168.0.0/24 的主机向 192.168.1.255/24 的目标地址发送 IP 包。收到这个包的路由器,将数据转发给 192.168.1.0/24,从而使得所有 192.168.1.1~192.168.1.254 的主机都能收到这个包
    • 多播用于将包发送给特定组内的所有主机

      • 多播使用的 D 类地址,其前四位是 1110 就表示是多播地址,而剩下的 28 位是多播的组编号。

        224.0.0.0 ~ 239.255.255.255 都是多播的可用范围,其划分为以下三类:

        • 224.0.0.0 ~ 224.0.0.255 为预留的组播地址,只能在局域网中,路由器是不会进行转发的
        • 224.0.1.0 ~ 238.255.255.255 为用户可用的组播地址,可以用于 Internet 上
        • 239.0.0.0 ~ 239.255.255.255 为本地管理组播地址,可供内部网在内部使用,仅在特定的本地范围内有效
          • 、

      环回地址是在同一台计算机上的程序之间进行网络通信时所使用的一个默认地址。

      计算机使用一个特殊的 IP 地址 127.0.0.1 作为环回地址。与该地址具有相同意义的是一个叫做 localhost 的主机名。使用这个 IP 或主机名时,数据包不会流向网络

    • 在分片传输中,一旦某个分片丢失,则会造成整个 IP 数据报作废,所以 TCP 引入了 MSS 也就是在 TCP 层进行分片不由 IP 层分片,那么对于 UDP 我们尽量不要发送一个大于 MTU 的数据报文

    • DHCP:电脑通常都是通过 DHCP 动态获取 IP 地址,大大省去了配 IP 信息繁琐的过程

    • NAT:两个私有 IP 地址都转换 IP 地址为公有地址 120.229.175.121,但是以不同的端口号作为区分

    • ICMP:确认 IP 包是否成功送达目标地址、报告发送过程中 IP 包被废弃的原因和改善网络设置等。 在 IP 通信中如果某个 IP 包因为某种原因未能达到目标地址,那么这个具体的原因将由 ICMP 负责通知。