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

139 阅读10分钟

01.简介

分析方法

自底向上

由简单到复杂

由局部到整体

自顶向下

由复杂到简单

将复杂的系统问题模块化处理

02.通过蟹堡王案例来理解计算机网络系统

蟹老板要管理遍布全国的蟹堡王分店需要很多基础设施,其中比较重要的一项为通信。

为了开通外卖服务,扩大服务范围,蟹堡王需要建立专属于蟹堡王的通信网络。

蟹堡王的服务模式与现实中的计算机网络系统有许多相近之处

  • 比奇堡外卖

  • 北京和上海分店

  • 全国分店和通信网络

  • 蟹堡王顾客:客户端

  • 蟹堡王分店:服务端

  • 小区转发点和蟹堡王城市转发分店:路由器

  • 转发表格网络协议

03.计算机网络基础

网络组成部分

  • 主机:客户端和服务端

  • 路由器

  • 网络协议

网络结构:网络的网络

  • 比奇堡和小区网络:本地网络

  • 北京和上海分店+比奇堡:三个本地网络节点的网络

  • 全国通信网络:本地网络的网络

以上三种网络可以称为区域网络,城域网,广域网

区域网络(Local area network,简称LAN)是连接住宅、学校、实验室、大学校园或办公大楼等有限区域内计算机的计算机网络。

城域网又称都会网络,指大型的计算机网络,是介于LAN和WAN之间能传输语音与资料的公用网络,这些网络通常涵盖一个大学校园或一座城市。 一些常用于城市区网的技术包含:异步传输模式(ATM)、光纤分布数据接口(FDDI)、千兆乙太网。

广域网(英语:Wide Area Network,缩写为WAN),又称外网、公网。 是连接不同地区局域网或城域网计算机通信的远程网。 通常跨接很大的物理范围,所覆盖的范围从几十公里到几千公里,它能连接多个地区、城市和国家,或横跨几个洲并能提供远距离通信,形成国际性的远程网络。 广域网并不等同于互联网。

信息交换的方式一般有两种:电路交换&分组交换

电路交换(Circuit Switching)是相对于封包交换(或称分组交换)的一个概念。 电路交换要求必须首先在通信双方之间建立连接通道。 在连接建立成功之后,双方的通信活动才能开始。 通信双方需要传递的信息都是通过已经建立好的连接来进行传递的,而且这个连接也将一直被维持到双方的通信结束。

分组交换(Packet switching)是一种相对于电路交换的通信范例,分组(又称消息、或消息碎片)在节点间单独路由,不需要在传输前先建立通信路径。 分组交换是数据通信中一种新的且重要的概念,现在是世界上互联网通讯、数据和语音通信中最重要的基础。

网络分层

计算机网络分为五层

从低到高为

物理层 链路层 网络层 运输层 应用层

每一层都有各自的职责,并对自身层级的内容进行分装,这些内容对于上一层几乎是黑盒的

类比于现实中的例子

  • 快递员不关心包裹内容

  • 卡车司机不关心车厢里拉的是什么

  • 高速公路不关心开的什么车

协议

协议的存在依赖于连接

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

标头(header)和载荷(payload)

HTTP 标头(header)允许客户端和服务器通过 HTTP 请求(request)或者响应(response)传递附加信息。一个 HTTP 标头由它的名称(不区分大小写)后跟随一个冒号(:),冒号后跟随它具体的值。该值之前的空格 (en-US)会被忽略。

报文的组成:链路层头部+IP协议头部+TCP头部+HTTP头部+HTTP正文

http协议

在http/1.1中,头部和载荷通过两个换行符和两个回车符进行分割(\r\n\r\n)

TCP协议

TCP协议中,最前面的2个字节是源端口号,往后的2个字节是目标端口号

接下来的8个字节分别是序列号(4字节)、ACK号(4字节)

TCP中头部和载荷的分割依靠图中Data offset部分(13~14字节)

在HTTP协议中,需要对ASCII码进行解析,得到二进制数据,发现有连续的换行符和回车符即为头部与载荷的分割

小结

  • 网络组成部分:由主机、路由器、交换机组成

  • 网络结构:网络的网络

  • 信息交换方式:电路交换和分组交换

  • 网络分层:分清职责,物理层、链路层、网络层、运输层和应用层

  • 网络协议:标头和载荷

04.Web中的网络

HTTP协议

在这个示例中,红色的是请求,蓝色的是响应

HTTP请求

  • 第一行:GET / HTTP/1.1

这三项分别代表请求的方法、资源路径、HTTP版本

  • 其他几行:头部

每一行代表一个头部,头部的名称和头部的值用冒号分割

头部名称不区分大小写

  • 正文与头部间隔一行(此示例中没有头部)

HTTP响应

  • 第一行:HTTP/1.1 200 OK

状态行

这三项分别代表HTTP版本、状态码、状态信息(可以自定义)

  • 其他几行:头部(与HTTP请求类似)

  • 正文与头部间隔一行

HTTP连接模型(请求响应模型)

当客户端发起第一个请求后,需要等待服务端发送第一个的完整响应,客户端才可以发出第二个请求

缺点:无法进行多路复用

Short-lived connections(HTTP/1.0):

Persistent connection(HTTP/1.1):

HTTP Pipeling:

允许客户端发送多个请求,服务器按顺序响应

但对于解决队头堵塞几乎没有帮助

为解决队头堵塞问题,最常用的方案是同时建立多个HTTP连接,将请求分散在多个HTTP连接上

浏览器一般会限制HTTP连接的数量,通常是6个

HTTP1.1:无法多路复用

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

如果按行交错发送,客户端收到的内容将会是

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

无法判断流中的哪一行都是属于哪个请求,因此无法实现多路复用

HTTP2:帧

将多个HTTP请求拆分到帧中,每个帧可以携带来自不同HTTP请求的数据(此处的帧和链路层的帧并非同一种,只是原理类似)

可以标识哪个数据包来自哪个请求,进而实现多路复用

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

HTTP帧的结构

最开始的3个字节:帧的长度

第4个字节:帧的类型

第5个字节:当前帧的状态

第6个字节:第1位是保留位,后面的31位代表这个帧所属流的ID

后面为帧的载荷

HTTP2:帧带来的额外好处

  • 调整响应传输的优先级

  • 头部压缩

  • Server Push

HTTP 2:队头堵塞,但是在TCP上

由于TCP对上层数据缺乏必要的信息(包1不影响包0、2、3),导致队头堵塞

这个问题很难再已有的TCP协议上解决

HTTP 2:3RTT启动

TCP连接建立需要一个RTT

TLS连接建立需要两个RTT

效率很低

HTTP 3:QUIC

QUIC将TLS作为自身的一部分,吸取HTTP 2中流的概念

同时引入新的机制,实现首次1 RTT,后续连接0 RTT的特性

  • Quick UDP Internet Connection

  • 现存网络设备对TCP和UDP支持已经僵化

  • UDP不靠谱但是QUIC靠谱

  • QUIC可以为除HTTP协议以外的应用层协议提供支持

HTTP 3:QUIC-1 RTT

QUIC实现首次1 RTT,后续连接0 RTT的过程

除HTTP外,还有很多因素会影响浏览器的性能

CDN:你无法突破的物理极限

超远距离因素无法克服

流量越大,花销越大

服务器承载网络流量有限

CDN可以承担内容分发的任务

CDN:DNS劫持

  • 域名解析一般由网站自己处理

  • 要加速的域名则重定向到CDN厂商的域名解析服务处理

  • CDN厂商根据来源确定最近的CDN服务器的IP

  • 用户直接访问最近的CDN服务器

CDN:如何选择CDN服务器

一种比较简单的策略是,根据DNS查询来源IP的地理位置,确定最近的CDN服务器

但这并不是最好的策略

CDN:拉策略和推策略

CDN 加速策略有两种方式,分别是**「推模式」和「拉模式」**。

大部分 CDN 加速策略采用的是「拉模式」,当用户就近访问的 CDN 节点没有缓存请求的数据时,CDN 会主动从源服务器下载数据,并更新到这个 CDN 节点的缓存中。

可以看出,拉模式属于被动缓存的方式,与之相反的 「推模式」就属于主动缓存的方式。

如果想要把资源在还没有用户访问前缓存到 CDN 节点,则可以采用「推模式」,这种方式也叫 CDN 预热。

通过 CDN 服务提供的 API 接口,把需要预热的资源地址和需要预热的区域等信息提交上去,CDN 收到后,就会触发这些区域的 CDN 节点进行回源来实现资源预热。

CDN可以从物理层面解决HTTP无法解决的问题,进而提升web应用的性能

WebSocket

WebSocket有以下特点:

  • 有状态的持久连接

  • 服务端可以主动推送消息

  • 发送消息延迟比HTTP低

使用websocket协议需要在HTTP协议的基础上,双方进行协商

WebSocket:示例

//服务端代码
const { WebSocketServer } = require('ws');

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

wss.on('connection', function connection(ws) {
    //有新连接时监听来自客户端的消息
    ws.on('message', function message(data) {
        //打印收到的消息,再把消息原封不动地发回客户端
        console.log('received: %s', data);
        ws.send(data);
    });
});
//客户端代码
const WebSocket = require('ws');

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

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

ws.on('message', function message(data) {
    //当收到来自服务器端的消息时,打印出来
    console.log('received: %s', data);
});

升级HTTP为WebSocket

WebSocket:发送消息

小结

  • HTTP1、2、3的演进历史

  • CDN解决了HTTP协议以外的问题

  • WebSocket从HTTP协议升级而来

05.网络安全

网络安全:三要素

  • 机密性

  • 完整性

  • 身份验证

网络安全:对称加密和非对称加密

  • 对称加密:加密、解密用同样的密钥

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

网络安全:密码散列函数(哈希函数)

  • 输入:任意长度的内容

  • 输出:固定长度的哈希值

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

网络安全:机密性

  • 加密需要加密算法和密钥等信息(秘密信息)

  • 网络是明文的,不安全

网络安全:完整性和身份验证

完整性和身份验证相关联

网络安全:如何实现机密性

想要通过明文通信交换秘密信息,通信双方需要先有秘密信息

网络安全:如何实现完整性

网络安全:如何实现身份验证

(未完待续)

让我先把当天的笔记发上去,有时间补上后面的