计算机网络概论 | 青训营笔记

106988222_p0

参考了这篇博客计算机网络概论 | 青训营笔记,并加入了一些分析思考

前言 & 课程介绍

这节课

  • 通过一个示例建立对计算机网络的整体认识
  • 建立对网络协议分层的认知
  • 分析HTTP1、2、3的关系
  • 介绍CDN运行的基本原理
  • 了解网络安全的最基本原则

这节课不会

  • 详细描述如何开发一个基于HTTP协议(或者其他协议)的网络应用
  • 深入介绍课程中所涉及协议的规范(Specification)内容和实现细节

image

计算机网络基础

网络组成部分

  • 主机:客户端和服务端(负责提供信息或者接收信息)
  • 路由器(负责转发主机之间的信息)
  • 网络协议(负责统一格式便于主机和路由器对信息的编码与解码)

image

网络结构: 网络的网络

  • 区域网络、城域网和广域网
  1. 区域网络(Metropolitan Area Network,简称 MAN):区域网络覆盖一个城市或城市群,比本地网络(LAN)的范围更大,但比广域网(WAN)小。典型的应用场景包括连接同一城市内的多个企业办公楼、大学校园、政府机构等。区域网络通常使用高速光纤或其他高速传输介质,可以提供较高的数据传输速率。
  2. 城域网(Campus Area Network,简称 CAN):城域网是指覆盖一个学校、大学或企业园区范围内的计算机网络。城域网的规模介于本地网络(LAN)和区域网络(MAN)之间。城域网通常由多个相互连接的局域网组成,以实现资源共享、通信和数据传输。城域网可以使用有线(如以太网)和无线(如 Wi-Fi)连接。
  3. 广域网(Wide Area Network,简称 WAN):广域网覆盖一个很大的地理区域,如国家、地区甚至全球。广域网通过远程通信链路和中继设备连接多个本地网络、区域网络和城域网。典型的广域网应用包括互联网、电话公司的网络和大型企业的全球网络。广域网的数据传输速率通常较低,因为它们需要跨越更大的距离并涉及更多的中继设备。

这些网络类型之间的主要区别在于覆盖范围、传输速率和管理复杂性。不同类型的网络适用于不同的应用场景,如资源共享、通信和数据传输

信息交换方式

电路交换(Circuit Switching): 电路交换最早用于电话系统,主要用于语音通信。在电路交换中,通信双方之间建立一条固定的、专用的物理通信路径。在通话过程中,这条路径会一直被保留,直到通话结束。数据沿着这条路径顺序传输。

分组交换(Packet Switching): 分组交换是现代计算机网络(如互联网)中主要使用的通信技术。在分组交换中,数据被切分成多个数据包(或称分组),每个数据包独立传输。数据包在网络中根据最佳路由选择相应的路径,最终在目的地重新组装成原始数据。

网络分层

  1. 物理层和数据链路层(Physical and Data Link Layers): 负责处理数据链路的建立、维护和断开,以及物理介质上的比特流传输和信号编码等任务。
  2. 网络层(Network Layer): 负责处理网络寻址和路由选择,以确定数据包从源节点到目的节点的最佳路径。
  3. 传输层(Transport Layer): 负责提供端到端的通信服务,包括数据的分段、传输、重组和确认。传输层还负责处理流量控制和差错控制。
  4. 应用层(Application Layer): 这个层次结合了 OSI 模型中的会话层、表示层和应用层,负责处理与特定应用程序相关的通信任务,以及数据的表示和编码问题。

网络协议

协议的存在依赖于链接

协议的存在避免了以错误的方式解读数据

协议定义了在两个或多个通信实体之间交换的报文格式顺序,以及报文发送和/或接受一条报文或其他事件所采取的动作。

HTTP协议示例

image

链路层-本地帧头部

image

链路层-IP协议头部

image

运输层-TCP协议头部

image

应用层-HTTP协议头部

image

TCP协议格式

image

Web中的网络

HTTP

http报文=链路协议头+ip协议头+TCP协议头+http协议头+http正文

http1.1及以前版本中,头部和载荷是通过两个换行符和回车符进行划分的

image

其中红色部分为请求,蓝色部分为相应

请求

GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
  • 请求行(Request Line):GET /index.html HTTP/1.1。请求行包含了请求方法(GET)、请求资源的路径(/index.html)和 HTTP 协议版本(HTTP/1.1)。
  • Host:www.example.com。Host 头部指定了请求的目标服务器域名。
  • User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36。User-Agent 头部描述了发起请求的客户端(浏览器)的信息,包括操作系统、浏览器类型和版本等。
  • Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8。Accept 头部表示客户端支持接收的 MIME 类型。在这个示例中,客户端支持接收 HTML、XHTML、XML 和 WebP 等格式的内容。
  • Accept-Language:en-US,en;q=0.5。Accept-Language 头部表示客户端支持的语言和优先级。在这个示例中,客户端优先支持美国英语,其次是其他英语。
  • Connection:keep-alive。Connection 头部表示连接的控制选项。在这个示例中,keep-alive 表示客户端希望保持连接,以便在多个请求之间复用 TCP 连接。

响应

HTTP 协议中的响应是服务器针对客户端请求所作出的回应。响应消息包含状态行、响应头部和响应体三部分。以下是一个简化的 HTTP 响应示例:

HTTP/1.1 200 OK
Date: Mon, 23 May 2022 22:38:34 GMT
Server: Apache/2.4.1 (Unix)
Content-Type: text/html; charset=UTF-8
Content-Length: 138
Last-Modified: Sun, 22 May 2022 15:28:12 GMT
Connection: close

<!DOCTYPE html>
<html>
<head>
    <title>Example Page</title>
</head>
<body>
    <h1>Hello, XiaoYu!</h1>
</body>
</html>
  • 状态行(Status Line):HTTP/1.1 200 OK。状态行包含 HTTP 协议版本(HTTP/1.1)、状态码(200)和状态描述(OK)。状态码 200 表示请求已成功处理。
  • Date:Mon, 23 May 2022 22:38:34 GMT。Date 头部表示响应生成的日期和时间。
  • Server:Apache/2.4.1 (Unix)。Server 头部描述了生成响应的服务器软件和版本信息。
  • Content-Type:text/html; charset=UTF-8。Content-Type 头部指定了响应体的媒体类型(MIME 类型)和字符编码。在这个示例中,响应体的内容是 HTML 格式,字符编码为 UTF-8。
  • Content-Length:138。Content-Length 头部表示响应体的字节长度。
  • Last-Modified:Sun, 22 May 2022 15:28:12 GMT。Last-Modified 头部表示请求资源的最后修改时间。
  • Connection:close。Connection 头部表示连接的控制选项。在这个示例中,close 表示服务器在发送完响应后将关闭 TCP 连接。
  • 响应体(Response Body):响应体包含实际返回的数据,通常是 HTML、JSON、XML 等格式的内容。在这个示例中,响应体是一个简单的 HTML 页面。

HTTP连接模型

  1. 无连接模型: 在早期的 HTTP/1.0 版本中,HTTP 使用无连接模型。这意味着每个 HTTP 请求和响应都需要建立一个新的 TCP 连接。在处理完一个请求后,服务器会关闭连接。这种模型简单易实现,但在高延迟和大量并发请求的场景下,性能较差。每个连接的建立和关闭都会消耗资源和时间,导致延迟增加和服务器负载过高。
  2. 持久连接模型: 为了解决无连接模型的性能问题,HTTP/1.1 引入了持久连接(Persistent Connection)模型,也称为 Keep-Alive 连接。在持久连接模型中,客户端和服务器可以在一个 TCP 连接上发送多个 HTTP 请求和响应。这种模型减少了 TCP 连接的建立和关闭次数,降低了延迟和服务器负载,提高了性能。持久连接在 HTTP/1.1 中是默认启用的,可以通过 Connection 请求头部的值(Keep-Alive 或 close)进行控制。
  3. 管道化连接模型: HTTP/1.1 还引入了管道化(Pipelining)连接模型,它允许客户端在收到上一个请求的响应之前,连续发送多个请求。服务器会按照请求的顺序依次处理,并按顺序返回响应。这种模型进一步提高了连接的利用率和性能。但由于实际部署中的兼容性和实现问题,HTTP/1.1 的管道化并未广泛应用。

image

这种模型无法避免一种问题:队头堵塞(Head of Line Blocking)

而且HTTP1.1无法多路复用

例如你发送

console.log('hello');
body{
    color: red;
}

结果变成了

body{
console.log('hello');
    color: red;
}

HTTP2

HTTP2下的完整过程

image

于是在HTTP2中出现了帧的概念

在 HTTP/2 中,帧(Frame)是协议的基本传输单位。HTTP/2 将请求和响应消息分解为多个小的二进制帧,这些帧在客户端和服务器之间传输。每种类型的帧都有特定的目的和格式。使用帧可以实现更高效的多路复用,避免队头阻塞问题,提高传输性能。

request=style.css, content='body {' 
request=main.js, content='console.log('hello');' 
request=style.css, content='    color: red;' 
request=style.css, content='}'

帧的组成

image

一个 HTTP/2 帧按顺序由以下几部分组成:

  1. 长度(Length):一个 24 位无符号整数,表示帧的负载长度(不包括帧头部的 9 个字节)。长度最大值为 2^24 - 1 字节(约 16MB)。

    image

  2. 类型(Type):一个 8 位无符号整数,表示帧的类型。不同类型的帧用于传输不同类型的信息,如 HEADERS、DATA、SETTINGS 等。

    image

  3. 标志(Flags):一个 8 位无符号整数,表示帧的特定属性。每种类型的帧都有自己的标志集合,用于控制帧的行为。

    image

  4. 保留位(R):一个 1 位保留位,目前未使用,必须设置为 0。

  5. 流标识符(Stream Identifier):一个 31 位无符号整数,表示帧所属的流。流是 HTTP/2 中的一个基本概念,每个请求和响应都有一个独立的流。流标识符为 0 的帧表示与整个连接相关的控制帧,而非特定流。

    image

  6. 负载(Payload):帧的负载数据,长度由 Length 字段指定。负载的内容和格式取决于帧的类型和标志。

    image

帧带来的额外好处

  • 调整响应传输的优先级
  • 头部压缩
  • Server Push

TCP

HTTP2:队头堵塞,但是在TCP上

TCP包0:包含了(包含了style.css的第1行内容)的HTTP2的帧
TCP包1:包含了(包含了main.js的全部内容)的HTTP2的帧
TCP包2:包含了(包含了style.css的第2行内容)的HTTP2的帧
TCP包3:包含了(包含了style.css的第3行内容)的HTTP2的帧

如果某个包丢包了,那客户端会向服务器请求再发送一次这个包

3 RTT启动

  • Round-Trip Time

TCP 和 TLS 握手:HTTP/2 基于 TCP 协议,建立一个新连接时需要进行 TCP 三次握手。如果使用 HTTPS(基于 TLS 的 HTTP),还需要进行 TLS 握手。这些握手过程增加了连接建立的延迟。特别是在移动网络环境中,这种延迟可能对用户体验产生较大影响。

image

HTTP3: QUIC

  • Quick UDP Internet Connection
  • 现存网络设备对TCP和UDP支持已经僵化
  • UDP不靠谱(包丢了就不管了,业务给多少数据,它就发多少数据)但是QUIC靠谱
  • QU1C可以为除HTP协议以外的应用层协议提供支持

QUIC 基于 UDP(User Datagram Protocol),而非 TCP,具有以下优势:

避免队头阻塞:QUIC 支持多路复用,且每个流在传输层上独立处理,因此一个流上的数据包丢失不会影响其他流。这样,在面对丢包和网络不稳定的情况下,QUIC 可以在面对丢包和网络不稳定的情况下,QUIC 可以实现更低的延迟,提高性能和用户体验。

更快的连接建立:由于 QUIC 基于 UDP,它将传输层和加密层的握手过程合并,从而减少了握手次数。这可以减少连接建立的延迟,尤其在网络环境不佳的情况下,对用户体验有很大帮助。

连接迁移:QUIC 支持连接迁移,当用户设备的网络环境发生变化时,可以实现平滑地从一个网络切换到另一个网络,而不会影响到已有的连接。这有助于减少延迟和资源浪费,提高用户体验。

错误恢复:QUIC 在丢包恢复方面比 TCP 更加高效,因为它可以更快地识别丢失的数据包并进行重传。这有助于减少延迟和提高传输性能。

HTTP/3 的出现主要是为了解决 HTTP/2 在面对丢包和网络不稳定的情况下的性能问题。通过引入基于 UDP 的 QUIC 协议,HTTP/3 解决了队头阻塞问题,实现了更快的连接建立和连接迁移,提高了错误恢复效率。这使得 HTTP/3 在网络环境不佳的情况下仍能提供良好的性能和用户体验。

img

image

CDN

CDN (Content Delivery Network),内容分发网络。CDN就是采用更多的缓存服务器(CDN边缘节点),布放在用户访问相对集中的地区或网络中。当用户访问网站时,利用全局负载技术,将用户的访问指向距离最近的缓存服务器上,由缓存服务器响应用户请求。

CDN 的主要组成部分包括:

  1. 边缘服务器(Edge Server):位于各地的服务器,用于缓存和分发内容。当用户请求内容时,CDN 会将请求重定向到最近的边缘服务器,从而加快访问速度。边缘服务器之间会根据一定的策略进行内容同步,确保缓存的内容是最新的。
  2. 负载均衡器(Load Balancer):用于在多个边缘服务器之间分发用户请求。负载均衡器根据各边缘服务器的负载情况和用户的地理位置,智能地将请求分配到合适的边缘服务器。
  3. 域名解析系统(DNS):CDN 通常会有自己的 DNS 服务,用于将用户的请求重定向到最近的边缘服务器。当用户访问一个使用 CDN 的网站时,DNS 会根据用户的 IP 地址和边缘服务器的位置信息,返回最近的边缘服务器 IP 地址,从而实现请求的重定向。
  4. 内容管理系统(CMS):用于管理和维护 CDN 中的内容。内容提供者可以通过 CMS 将内容发布到 CDN,并对内容进行更新、删除等操作。

CDN 的主要优点包括:

  1. 降低延迟:通过将内容缓存到离用户更近的边缘服务器上,CDN 可以显著降低访问延迟,提高用户体验。
  2. 提高可用性:CDN 能够在多个边缘服务器之间分发流量,从而提高系统的冗余性。当某个边缘服务器出现故障时,用户的请求可以被重新定向到其他可用的服务器,确保服务的正常运行。
  3. 减轻源站压力:由于大部分用户请求都被 CDN 的边缘服务器处理,源站服务器的压力得到了缓解,从而降低了源站的成本和维护复杂性。
  4. 节省带宽:CDN 可以通过缓存和压缩技术,有效地减少网络带宽的消耗,降低数据传输成本。
  5. 安全性:CDN 可以提供诸如 DDoS(分布式拒绝服务)攻击保护、Web 应用程序防火墙等安全措施,保护网站免受攻击和恶意访问。
  6. 支持动态内容:除了静态内容外,CDN 还可以缓存和分发动态内容,如动态生成的 HTML 页面、Web API 的响应等。

DNS劫持

  • 域名解析一般由网站自己处理
  • 要加速的域名则重定向到CDN厂商的域名解析服务处理(通常不是由自己来解析,而是由CDN厂商来做)
  • CDN厂商根据来源确定最近的CDN服务器的IP
  • 用户直接访问最近的CDN服务器

缓存策略

  • 拉取策略(Pull),也叫做就近访问策略,指的是 CDN 节点通过 HTTP 请求直接向源站请求数据,然后缓存到本地节点,当用户请求数据时,就直接从缓存的本地节点中获取数据。这种策略主要用于数据更新较少的情况,适用于流量较小、访问频率低的站点。

  • 推送策略(Push),也叫做预先访问策略,指的是将源站的数据推送到 CDN 节点,通过 HTTP 请求缓存到 CDN 节点,当用户请求数据时,直接从缓存的本地节点中获取数据。这种策略适用于数据更新频繁的情况(比如视频举例的热门新电影上线的时候,就可以使用推送策略,全国用户可以第一时间 获取新电影),可以有效地缓解源站的访问压力,提高用户访问速度。推送策略需要源站和 CDN 之间建立预先配置好的链接,源站通过这个链接将数据推送到 CDN 节点。

WebSocket

WebSocket 是一种网络通信协议,可以在客户端和服务器之间实现双向通信。与传统的 HTTP 协议不同,WebSocket 协议在客户端和服务器之间建立持久连接,可以在任何时间点双向通信,而不需要通过 HTTP 请求和响应来进行。WebSocket 协议可以在 Web 应用程序和服务器之间实现实时通信和数据传输,常用于在线游戏、聊天室、实时数据监测等场景。

WebSocket 协议的优点如下:

  1. 实时性:WebSocket 协议可以在客户端和服务器之间实现双向实时通信,可以在任何时间点发送和接收数据,避免了 HTTP 请求和响应的延迟和重复。
  2. 效率:WebSocket 协议可以在客户端和服务器之间建立持久连接,避免了每次请求和响应的开销,提高了数据传输效率。
  3. 跨域支持:WebSocket 协议可以支持跨域通信,可以在不同的域名和端口之间进行数据传输。
  4. 可扩展性:WebSocket 协议可以通过自定义消息格式和协议扩展实现更复杂的应用场景和功能。

WebSocket 协议的实现基于 TCP 协议,使用类似 HTTP 的握手协议建立连接。客户端和服务器之间建立连接后,可以通过 send() 方法发送数据,通过 onmessage() 方法接收数据。客户端和服务器之间的通信是双向的,可以在任何时间点发送和接收数据。当客户端或服务器需要关闭连接时,可以调用 close() 方法关闭连接。

总之,WebSocket 协议是一种实现双向实时通信的网络通信协议,可以在 Web 应用程序和服务器之间实现实时数据传输和通信。WebSocket 协议可以提高数据传输效率和实时性,适用于在线游戏、聊天室、实时数据监测等场景。

  • 有状态的持久连接
  • 服务端可以主动推送消息
  • 用WebSocket发送消息延迟比HTTP低

服务端代码示例

const {WebSocketServer} = require('ws');
const wss = new WebSocketServer({port: 8080});

wss.on('connection', function connection(ws) {
    // 有新链接时监听来着客户端的消息
    ws.on('message', function incoming(message) {
    // 打印客户端发送的消息,并原封不动的返回给客户端
        console.log('received: %s', message);
        ws.send(message);
    });
});

客户端代码示例

const WebSocket = require('ws');

const ws = new WebSocket('ws://localhost:8080');

ws.on('open', function open() {
    // 当连接建立时发送一条消息给服务器
    ws.send('something');
});

ws.on('message', function incoming(data) {
    // 接收到服务器发送的消息
    console.log('received: %s',data);
});

网络安全

对称加密和非对称加密

  • 对称加密:加密、解密用同样的密钥
  • 非对称加密:加密、解密使用不同的密钥(公钥和私钥),而且公钥加密只能用私钥解密、私钥加密只能用公钥解密

密码散列函数(哈希函数)

  • 输入:任意长度的内容
  • 输出:固定长度的哈希值
  • 性质:找到两个不同的输入使之经过密码散列函数后有相同的哈希值,在计算上是不可能的

网络安全三要素

机密性

机密性指攻击者无法获知通信内容

  • 已知:网络是明文的
  • 如果双方可以通过明文通信商量出秘密信息,那么攻击者也可以
  • 所以想要通过明文通信交换秘密信息,通信双方需要先有秘密信息

完整性

完整性指攻击者对内容进行篡改时能被发现

  • 密码散列函数性质:找到两个不同的输入使之经过密码散列函数后有相同的哈希值,在计算上是不可能的
  • 有明文m,密码散列函数H,以及一个密钥 s
  • 计算H(m+s)获得哈希值h
  • 将m和h组合成新信息m+h
  • 接收方拆分m+h,重新计算H(m+s)得h',对比h'和h

所以想要实现完整性,通信双方需要先有秘密信息

身份验证

完整性和身份验证相互关联。

身份验证指攻击者无法伪装成通信双方的任意一方与另一方通信

  • 签名:用于鉴别身份和防止伪造
  • 非对称加密性质:加密、解密使用不同的密钥(公钥和私钥),而且公钥加密只能用私钥解密、私钥加密只能用公钥解密
  • 蟹老板用自己的私钥对信件进行加密,并发送给海绵宝宝
  • 海绵宝宝使用蟹老板的公钥进行解密,获得原文
  • 保证了机密性、完整性和身份验证

数字签名

  • 数字签名:对明文内容的哈希值使用私钥加密,验证者使用公钥验证
  • 数字签名(指纹)=私钥加密(密码散列函数(原文))
  • 消息=原文+数字签名
  • 一般用于对公开内容(如包含公钥的证书)进行数字签名,防止篡改

证书链 & PKI

  • 可信的人验证蟹老板的公钥
  • 那谁验证可信的人的公钥?
  • 根证书是证书链的尽头
  • 验证的一连串证书称为证书链
  • 分发证书、验证证书的基础设施称为PKI, Public Key Infrastructure
  • 所以想要实现身份验证,通信双方需要先有秘密信息,即根证书中的公钥

PKI保证了普通用户不需要“面对面”和根证书机构交换根证书

证书链示例

image

image

HTTPS

把HTTP的明文换成密文,再验证身份,即HTTPS。

HTTPS = HTTP + TLS
TLS = 身份验证 + 加解密
身份验证PKI

HTTPS 使用 PKI 完成了除客户端身份验证以外的特性,客户端身份验证靠 HTTP 协议实现
简单来说就是:服务端身份验证靠PKI,客户端身份验证靠HTTP协议。

参考文献和书籍推荐

posted @ 2023-05-15 11:09  520Enterprise  阅读(33)  评论(0编辑  收藏  举报