> For the complete documentation index, see [llms.txt](https://ryukiedev.gitbook.io/wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ryukiedev.gitbook.io/wiki/zhi-shi-dian-shu-li/zhi-shi-dian-shu-li-er-wang-luo.md).

# 04 知识点梳理：网络

### 一、 HTTPS 和 HTTP

***

![](/files/0Z2TZMPHv3lfzU4YuHJ0)

#### 1.1 HTTPS协议 = HTTP协议 + SSL/TLS协议

* `SSL`的全称是`Secure Sockets Layer`，即安全套接层协议，是为网络通信提供安全及数据完整性的一种安全协议。
* TLS的全称是`Transport Layer Security`，即安全传输层协议。

#### 1.2 即HTTPS是安全的HTTP

* `https`, 全称`Hyper Text Transfer Protocol Secure`，相比`http`，多了一个`secure`，这一个`secure`是怎么来的呢？
* 这是由`TLS（SSL）`提供的！大概就是一个叫`openSSL`的`library`提供的。
* `https`和`http`都属于`application layer`，基于TCP（以及UDP）协议，但是又完全不一样。
* TCP用的port是80， https用的是443（值得一提的是，google发明了一个新的协议，叫QUIC，并不基于TCP，用的port也是443， 同样是用来给https的。谷歌好牛逼啊。）总体来说，https和http类似，但是比http安全。

#### 1.3 HTTPS的握手流程

* 1：客户端发起HTTPS请求，将SSL协议版本的信息发送给服务端。
* 2：服务器收到之后，会以Server Hello 报文作为应答。和客户端一样，报文中包含客户端支持的SSL的版本，加密组件列表。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的
* 3：服务器发送Certificate报文。报文中包含公开密钥证书。
* 4：然后服务器发送Server Hello Done报文通知客户端，最初阶段的SSL握手协商部分结束
* 5：SSL第一次握手结束之后，客户端以Client Key Exchange报文作为会议。报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串
* 6：接着客户端发送Change Cipher Space报文。该报文会提示服务器，在次报文之后的通信会采用Pre-master secret密钥加密
* 7：客户端发送Finished 报文。该报文包含链接至今全部报文的整体校验值。这次握手协商是否能够成功，要以服务器是否能够正确揭秘该报文作为判定标准
* 8：服务器同样发送Change Cipher Space报文。
* 9：服务器同样发送Finished报文。
* 10：服务器和客户端的Finished报文交换完毕之后，SSL连接建立完成，从此开始HTTP通信，通信的内容都使用Pre-master secret加密。然后开始发送HTTP请求
* 11：应用层收到HTTP请求之后，发送HTTP响应
* 12：最后有客户端断开连接

#### 1.4 为什么密钥的传递需要使用非对称加密？

使用非对称加密是为了后面客户端生成的`Pre-master secret`密钥的安全，通过上面的步骤能得知，服务器向客户端发送公钥证书这一步是有可能被别人拦截的，如果使用对称加密的话，在客户端向服务端发送`Pre-master secret`密钥的时候，被黑客拦截的话，就能够使用公钥进行解码，就无法保证`Pre-master secret`密钥的安全了

#### 1.5 对称加密和非对称加密的区别？分别有哪些算法的实现？

**对称加密，加密的加密和解密使用同一密钥。**

* 非对称加密，使用一对密钥用于加密和解密，分别为公开密钥和私有密钥。公开密钥所有人都可以获得，通信发送方获得接收方的公开密钥之后，就可以使用公开密钥进行加密，接收方收到通信内容后使用私有密钥解密。
* 对称加密常用的算法实现有AES,ChaCha20,DES,不过DES被认为是不安全的;非对称加密用的算法实现有RSA，ECC

#### 1.6 双向认证了解么？

上面的HTTPS的通信流程只验证了服务端的身份，而服务端没有验证客户端的身份，双向认证是服务端也要确保客户端的身份，大概流程是客户端在校验完服务器的证书之后，会向服务器发送自己的公钥，然后服务端用公钥加密产生一个新的密钥，传给客户端，客户端再用私钥解密，以后就用此密钥进行对称加密的通信

#### 1.7 HTTP2.0 的特性

1. 内容安全
   * 应为 http2.0 是基于 https 的，天然具有安全特性，通过 http2.0 的特性可 以避免单纯使用 https 的性能下降
2. 二进制格式
   * http1.X 的解析是基于文本的，http2.0 将所有的传输信息分割为更小的 消息和帧，并对他们采用二进制格式编码，基于二进制可以让协议有更多的扩展性，比 如引入了帧来传输数据和指令
3. 多路复用
   * 这个功能相当于是长连接的增强，每个 request 请求可以随机的混杂在一 起，接收方可以根据 request 的 id 将 request 再归属到各自不同的服务端请求里面
   * 另外多路复用中也支持了流的优先级，允许客户端告诉服务器那些内容是更优先级的资源，可以优先传输。

### 二、 TCP

***

#### 2.1 三次握手

![](/files/QxqGTpGItDXhQrqq8k21)

TCP是面向连接的协议，建立连接需要经过`三次握手`

* 客户端向服务端发起请求链接，首先发送`SYN`报文，`SYN=1，seq=x`,并且客户端进入`SYN_SENT`状态
* 服务端收到请求链接，服务端向客户端进行回复，并发送响应报文，`SYN=1，seq=y,ACK=1,ack=x+1`,并且服务端进入到`SYN_RCVD`状态
* 客户端收到确认报文后，向服务端发送确认报文，`ACK=1，ack=y+1`，此时客户端进入到`ESTABLISHED`，服务端收到用户端发送过来的确认报文后，也进入到`ESTABLISHED`状态，此时链接创建成功

#### 2.2 四次挥手

![](/files/iknUZWRrl4T6tkGw5OYr)

TCP断开连接需要经过 `四次挥手`

* 客户端向服务端发起关闭链接，并停止发送数据
* 服务端收到关闭链接的请求时，向客户端发送回应，我知道了，然后停止接收数据
* 当服务端发送数据结束之后，向客户端发起关闭链接，并停止发送数据
* 客户端收到关闭链接的请求时，向服务端发送回应，我知道了，然后停止接收数据

#### 2.3 为什么需要三次握手

为了防止已失效的连接请求报文段突然又传送到了服务端，因而产生错误，假设这是一个早已失效的报文段。但`server`收到此失效的连接请求报文段后，就误认为是`client`再次发出的一个新的连接请求。于是就向`client`发出确认报文段，同意建立连接。假设不采用“三次握手”，那么只要server发出确认，新的连接就建立了。由于现在`client`并没有发出建立连接的请求，因此不会理睬`server`的确认，也不会向`server`发送数据。但`server`却以为新的运输连接已经建立，并一直等待`client`发来数据。这样，`server`的很多资源就白白浪费掉了。

#### 2.4 为什么需要四次挥手

因为TCP是全双工通信的，在接收到客户端的关闭请求时，还可能在向客户端发送着数据，因此不能再回应关闭链接的请求时，同时发送关闭链接的请求

#### 2.3 TCP/UDP

* `TCP`是传输控制协议，具有面向连接、可靠传输、点到点通信、全双工服务等特点，TCP侧重可靠传输。
* `UDP`是用户数据报协议，具有非连接的、不可靠的、点到多点的通信等特点，UDP侧重快速传输。

#### 2.4 TCP/IP协议

* `TCP/IP`不是一个协议，而是一个协议簇的统称。
* 通常使用的网络是在TCP/IP协议簇的基础上运行的。
  * **应用层**的`HTTP`、`DNS`、`FTP`，**传输层**的`TCP`(传输控制协议)、`UDP`(用户数据报协议)，**网络层**的`IP`等等都属于它内部的一个子集。

#### 2.5 TCP报文重点字段

`序号`：Seq序号，占32位，用来标识从TCP源端向目的端发送的字节流，发起方发送数据时对此进行标记。 `确认序号`：Ack序号，占32位，只有ACK标志位为1时，确认序号字段才有效，Ack=Seq+1。 `标志位`：共6个，即URG、ACK、PSH、RST、SYN、FIN等，具体含义如下：

* （A）`URG`：紧急指针（urgent pointer）有效。
* （B）`ACK`：确认序号有效。
* （C）`PSH`：接收方应该尽快将这个报文交给应用层。
* （D）`RST`：重置连接。
* （E）`SYN`：发起一个新连接。
* （F）`FIN`：释放一个连接。

#### 2.6 为什么不能用两次握手进行连接？

* 因为三次握手是为了双方都知道彼此已做好准备，如果改成两次握手，会发生 。
* 假设客户端给服务端发送连接请求，服务端收到后发送确认连接给客户端，如果两次握手的话此时服务端会认为已经建立了连接，可以发送数据了
* 但是如果确认连接数据丢失，客户端还不知道已经建立了连接
  * 会一直等待确认连接序号，导致数据传输超时
  * 服务端重复发送同样的数据，造成死锁。

#### 2.7 客户端进入`TIME_WAIT`状态而不是直接进入`CLOSED`状态是因为

我们必须要假想网络是不可靠的，你无法保证你最后发送的`ACK报文`一定会被对方收到

因此对方处于`LAST_ACK`状态下的`SOCKET`可能会因为超时未收到`ACK`报文，而重发FIN报文

所以这个`TIME_WAIT`状态的作用就是用来重发可能丢失的`ACK`报文。

### 五、 如何用Charles抓HTTPS的包？其中原理和流程是什么？

***

#### 5.1 流程

* 首先在手机上安装Charles证书
* 在代理设置中开启Enable SSL Proxying
* 之后添加需要抓取服务端的地址

#### 5.2 原理

`Charles`作为中间人，对客户端伪装成服务端，对服务端伪装成客户端。简单来说：

* 截获客户端的HTTPS请求，伪装成中间人客户端去向服务端发送HTTPS请求
* 接受服务端返回，用自己的证书伪装成中间人服务端向客户端发送数据内容。

具体流程如下图:[扯一扯HTTPS单向认证、双向认证、抓包原理、反抓包策略](https://juejin.im/post/5c9cbf1df265da60f6731f0a#heading-3)

![](https://user-gold-cdn.xitu.io/2019/12/26/16f41a2f14a97620?imageView2/0/w/1280/h/960/ignore-error/1)

### 六、 什么是中间人攻击？

***

中间人攻击就是截获到客户端的请求以及服务器的响应，比如`Charles`抓取HTTPS的包就属于中间人攻击。

#### 如何避免？

避免的方式：客户端可以预埋证书在本地，然后进行证书的比较是否是匹配的

### 八、 Socket

***

#### 1. WebSocket 与 TCP Socket的区别

***Socket***

* `Socket`是抽象层，并不是一个协议
  * 是为了方便使用TCP或UDP而抽象出来的一层，是位于应用层和传输层(TCP/UDP)之间的一组接口。

***WebSocket***

* `WebSocket`和HTTP一样，都是应用层协议
  * 是基于TCP 连接实现的双向通信协议，替代`HTTP轮询`的一种技术方案。
  * 是全双工通信协议，`HTTP`是单向的
  * 注意WebSocket和Socket是完全不同的两个概念。
* `WebSocket`建立连接时通过HTTP传输，
  * 但是建立之后，在真正传输时候是不需要HTTP协议的。
* 相对于传统 `HTTP` 每次请求-应答都需要客户端与服务端建立连接的模式，`WebSocket` 是类似 `Socket` 的 `TCP 长连接`的通讯模式，
* 一旦 `WebSocket` 连接建立后，后续数据都以帧序列的形式传输。
* 在客户端断开 `WebSocket` 连接或 `Server` 端断掉连接前，不需要客户端和服务端重新发起连接请求。
* 在海量并发及客户端与服务器交互负载流量大的情况下，极大的节省了网络带宽资源的消耗，有明显的性能优势，且客户端发送和接受消息是在同一个持久连接上发起，实时性优势明显。

#### 2. WebSocket 连接过程 —— 握手过程

* 1.浏览器、服务器建立TCP连接，三次握手。这是通信的基础，传输控制层，若失败后续都不执行。
* 2.TCP连接成功后，浏览器通过HTTP协议向服务器传送`WebSocket`支持的版本号等信息。（开始前的HTTP握手）
* 3.服务器收到客户端的握手请求后，同样采用`HTTP`协议回馈数据。
* 4.当收到了连接成功的消息后，通过`TCP`通道进行传输通信。

#### 3. Socket.IO

* `Socket.IO` 是一个为浏览器（客户端）和服务器之间提供实时，双向和基于事件的通信软件库。

`Socket.IO` 是把数据传输抽离成 Engine.IO，内部对轮询（Polling）和 WebSocket 等进行了封装，抹平一些细节和平台兼容的问题，提供统一的 API。

> 注意 `Socket.IO` 不是 `WebSocket` 的实现，只是在必要时使用 `WebSocket` 传输数据，并在此基础上会加一些 `MetaData`。这就是为什么 `WebSocket` 的客户端/服务器 无法和 `Socket.IO` 的服务器/客户端进行通信。

### 九、 POST和GET

***

![](https://raw.githubusercontent.com/RyukieSama/RyukieImage/master/Blog/POST-GET.png)

#### 9.1 POST安全?

> 其实也只是一点点罢了..

* get请求的URL会被缓存在浏览器及Web服务器日志里,可能泄露
* POST没有记录,只要数据服务器不被黑就安全
* 抓包的话GG(非HTTPS)

#### 9.2 GET相对POST最大的优势

可以手输URL

#### 9.3 何时使用GET

* 请求中的URL可以被手动输入
* 请求中的URL可以被存在书签里，或者历史里，或者快速拨号里面，或者分享给别人
* 请求中的URL是可以被搜索引擎收录的
* 带云压缩的浏览器，比如Opera mini/Turbo 2, 只有GET才能在服务器端被预取的
* 请求中的URL可以被缓存
* 可重复的交互例如: 取个数据,跳个页面用Get
  * 不可重复的操作如创建,修改就用POST

参考

> <https://www.zhihu.com/question/31640769?rf=37401322>

### 十、 网络分层

***

#### 1. 网络层级结构

TCP/IP四层结构

* 应用层
* 传输层
* 网络层
* 数据链路层
* 物理层

OSI七层网络结构

* 应用层
* 表示层
* 会话层
* 传输层
* 网络层
* 数据链路层
* 物理层

#### 2. 优点

> 面试被问到了,记录下

* 各层之间是独立的
  * 某一层并不需要知道它的下一层是怎么实现的,而仅仅需要知道该层通过层间接口所提供的接口服务
  * 由于每一层间只实现相对独立的功能,因而可以将一个难以处理的复杂问题分解为若干个较容易处理的更小的问题,这样问题的复杂度就降低了
* 灵活性好
  * 当某一层发生变化的时候只要层间关系保持不变,则这层的上下层均不受影响,此外,对某一层提供的服务还可以进行修改.当某一层提供的服务不再需要时,甚至可以将这层取消
* 结构上可分割开
  * 各层都可以采用最合适的技术来实现
* 易于实现和维护
  * 这种结构使得实现和调试一个庞大复杂的系统变得容易处理,因为整个系统已经被分解为若干个相对独立的子系统
* 能够促进标准化工作
  * 因为每一层的功能机器提供的服务都已经有了明确的说明
* 注意
  * 分层是应该注意每一层的功能非常明确,若层数太少,会使得每一层协议太复杂
  * 层数太多又会在描述和综述各功能的系统工程任务时遇到较多困难
