Skip to main content

计算机网络

基础知识

OSI七层模型

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

TCP/IP四层模型

应用层:应用层、表示层、会话层:HTTP

传输层:传输层:TCP/UDP

网络层:网络层:IP

数据链路层:数据链路层、物理层

HTTP

超文本传输协议,是客户端浏览器或其他程序与Web服务器之间的应用层通信协议,应用层协议,可以传输任意资源,可靠传输(基于TCP/IP),每次请求都是独立的,无关的,明文传输不安全,复用一个TCP链接会发生拥塞,无状态

HTTP协议历史:

  • 1.0 :

协议缺陷:⽆法复⽤链接,完成即断开

  • 1.1 :

改进: ⻓连接(默认 keep-alive ),复⽤ 新增功能: 断点续传 身份认证 状态管理 cache 缓存 Cache-Control Expires Last-Modified Etag

  • 2.0:

⼤幅度提⾼了⽹⻚的性能。 在 HTTP/1 中,为了性能考虑,我们会引⼊雪碧图、将⼩图内联、使⽤多个域名等等的⽅ 式。这⼀切都是因为浏览器限制了同⼀个域名下的请求数量(Chrome 下⼀般是限制六个 连接),当⻚⾯中需要请求很多资源的时候,队头阻塞(Head of line blocking)会导致在 达到最⼤请求数量时,剩余的资源需要等待其他资源请求完成后才能发起请求。

  1. 多路复用:在 HTTP/2 中引⼊了多路复⽤的技术,这个技术可以只通过⼀个TCP连接就可以传输所有的请求数据。有两个⾮常重要的概念,分别是帧(frame)和流(stream)。帧代表着最⼩的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。多路复⽤,就是在⼀个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免 HTTP 旧版本 中的队头阻塞问题,极⼤的提⾼传输性能。
  2. 二进制传输:之前的 HTTP 版本中,我们是通过⽂本的⽅式传输数据。在 HTTP/2 中引⼊了新的编码机制,所有传输的数据都会被分割,并采⽤⼆进制格式编码。
  3. Header 压缩:在 HTTP/1 中,我们使⽤⽂本的形式传输 header ,在 header 携带 cookie 的情况下,可能每次都需要重复传输⼏百到⼏千的字节。 在 HTTP / 2 中,使⽤HPACK 压缩格式对传输的 header 进⾏编码,减少了header 的⼤⼩。并在两端维护了索引表,⽤于记录出现过的header ,后⾯在传输过程中就可以传输已经记录过的 header 的键名,对端收到数据后就可以通过键名找到对应 的值。
  4. 服务端 Push:在 HTTP/2 中,服务端可以在客户端某个请求后,主动推送其他资源。可以想象以下情况,某些资源客户端是⼀定会请求的,这时就可以采取服务端 push 的技 术,提前给客户端推送必要的资源,这样就可以相对减少⼀点延迟时间。当然在浏览器兼容的情况下你也可以使⽤prefetch
  • 3.0:

    因为 HTTP/2 使⽤了多路复⽤,⼀般来说同⼀域名下只需要使⽤⼀个 TCP 连接。当这个 连接中出现了丢包的情况,那就会导致 HTTP/2 的表现情况反倒不如 HTTP/1了。因为在出现丢包的情况下,整个 TCP 都要开始等待重传,也就导致了后⾯的所有数据都被阻塞了。但是对于 HTTP/1来说,可以开启多个 TCP 连接,出现这种情况反到只会影 响其中⼀个连接,剩余的 TCP 连接还可以正常传输数据。

    :::tip 基于 UDP 协议的 QUIC 协议 效率很⾼,但是并不可靠。QUIC虽然基于UDP,但是在原本的基础上新增了很多功能,⽐如多路复⽤、0-RTT、使⽤TLS1.3加密、流量控制、有序交付、重传等等功能。 :::

  • Https:

HTTPS还是通过HTTP来传输信息,但是信息通过TLS协议进行了加密,是较为安全的⽹络传输协议,可以理解为HTTP+SSL/TLS,TLS 协议位于传输层之上,应⽤层之下。⾸次进⾏ TLS 协议传输需要两个 RTT ,接下来可以通过 Session Resumption 减少到⼀个 RTT。SSL加密端口:443

对称加密

对称加密就是两边拥有相同的秘钥,两边都知道如何将密⽂加密解密。这种加密⽅式固然很好,但是问题就在于如何让双⽅知道秘钥。因为传输数据都是⾛的⽹络,如果将秘钥通过⽹络的⽅式传递的话,⼀旦秘钥被截获就没有加密的意义的

非对称加密
  1. 有公钥私钥之分,公钥所有⼈都可以知道,可以将数据⽤公钥加密,但是将数据解密必须使⽤私钥解密,私钥只有分发公钥的⼀⽅才知道。这种加密⽅式就可以完美解决对称加密存在的问题。假设现在两端需要使⽤对称加密,那么在这之前,可以先使⽤⾮对称加密交换秘钥
  2. ⾸先服务端将公钥公布出去,那么客户端也就知道公钥了。接下来客户端创建⼀个秘钥,然后通过公钥加密并发送给服务端,服务端接收到密⽂以后通过私钥解密出正确的秘钥,这时候两端就都知道秘钥是什么了。
  • TLS握手

TLS 握⼿阶段,两端使⽤⾮对称加密的⽅式来通信,但是因为⾮对称加密损耗的性能⽐对称加密⼤,所以在正式传输数据时,两端使⽤对称加密的⽅式通信。

过程
  1. 客户端发送⼀个随机值以及需要的协议和加密⽅式。
  2. 服务端收到客户端的随机值,⾃⼰也产生⼀个随机值,并根据客户端需求的协议和加密⽅ 式来使⽤对应的⽅式,并且发送⾃⼰的证书(如果需要验证客户端证书需要说明)
  3. 客户端收到服务端的证书并验证是否有效,验证通过会再⽣成⼀个随机值,通过服务端证书的公钥去加密这个随机值并发送给服务端,如果服务端需要验证客户端证书的话会附带证书
  4. 服务端收到加密过的随机值并使⽤私钥解密获得第三个随机值
  5. 这时候两端都拥有了三个随机值,可以通过这三个随机值按照之前约定的加密⽅式⽣成密钥,接下来的通信就可以通过该密钥来加密解密
  • 其他加密算法
  1. 哈希算法

将任意长度的信息转换为较短的固定长度的值,通常其长度要比信息小得多,且算法不可逆。

例如:MD5、SHA-1、SHA-2、SHA-256 等

  1. 数字签名

签名就是在信息的后面再加上一段内容(信息经过hash后的值),可以证明信息没有被修改过。hash值一般都会加密后(也就是签名)再和信息一起发送,以保证这个hash值不被修改。

报文结构

  1. request报文结构
  • 请求方法+请求url+协议版本
  • 请求头
  • 消息实体
  1. response报文结构
  • 状态码+状态描述+协议版本
  • 响应头
  • 消息实体

请求方法

get,post,head,put,delete,connect,options,trace,patch

get和post区别
  1. Get 请求能缓存, Post 不能
  2. Post 相对 Get 安全⼀点点,因为 Get 请求都包含在 URL ⾥,且会被浏览器保存历 史纪录, Post 不会,但是在抓包的情况下都是⼀样的。
  3. Post 可以通过 request body 来传输⽐ Get 更多的数据, Get 没有这个技术
  4. URL 有⻓度限制,会影响 Get 请求,但是这个⻓度限制是浏览器规定的,不是 RFC 规 定的
  5. Post ⽀持更多的编码类型且不对数据类型限制

常见状态码

2XX 成功
200 OK ,表示从客户端发来的请求在服务器端被正确处理
204 No content ,表示请求成功,但响应报⽂不含实体的主体部分
205 Reset Content ,表示请求成功,但响应报⽂不含实体的主体部分,但是与 204
响应不同在于要求请求⽅重置内容
206 Partial Content ,进⾏范围请求 3XX 重定向
301 moved permanently ,永久性重定向,表示资源已被分配了新的 URL
302 found ,临时性重定向,表示资源临时被分配了新的 URL
303 see other ,表示资源存在着另⼀个 URL,应使⽤ GET ⽅法丁⾹获取资源
304 not modified ,表示服务器允许访问资源,但因发⽣请求未满⾜条件的情况
307 temporary redirect ,临时重定向,和302含义类似,但是期望客户端保持请求⽅ 法不变向新的地址发出请求 4XX 客户端错误
400 bad request ,请求报⽂存在语法错误
401 unauthorized ,表示发送的请求需要有通过 HTTP 认证的认证信息
403 forbidden ,表示对请求资源的访问被服务器拒绝
404 not found ,表示在服务器上没有找到请求的资源 5XX 服务器错误
500 internal sever error ,表示服务器端在执⾏请求时发⽣了错误
501 Not Implemented ,表示服务器不⽀持当前请求所需要的某个功能
503 service unavailable ,表明服务器暂时处于超负载或正在停机维护,⽆法处理请求

TCP和UDP

区别

TCP 基本是和 UDP 反着来,建⽴连接断开连接都需要先需要进⾏握⼿。在传输数据的过程中,通过各种算法保证数据的可靠性,当然带来的问题就是相⽐ UDP 来说不那么的⾼效

UDP

无连接,不可靠,没有拥塞控制,头部开销小,只有八字节,在传输数据报文时是很高效的。

caution

在发送端,应用层将数据传递给传输 层的UDP协议,UDP只会给数据增加一个UDP头标识是UDP协议,然后就传递给网络层了。 在接收端,网络层将数据传递给传输层,UDP只去除IP报文头就传递给应用层,不会有任何拼接操作。

TCP

无连接(HTTP 是⽆连接的,所以作为下层的 TCP 协议也是⽆连接的,虽然看似TCP 将两端连接了起来,但是其实只是两端共同维护了⼀个状态)

头部字段

URG=1 :该字段为⼀表示本数据报的数据部分包含紧急信息,是⼀个⾼优先级数据报⽂, 此时紧急指针有效。紧急数据⼀定位于当前数据包数据部分的最前⾯,紧急指针标明了紧 急数据的尾部。 ACK=1 :该字段为⼀表示确认号字段有效。此外, TCP 还规定在连接建⽴后传送的所有 报⽂段都必须把 ACK 置为⼀ PSH=1 :该字段为⼀表示接收端应该⽴即将数据 push 给应 ⽤层,⽽不是等到缓冲区满后再提交。 RST=1 :该字段为⼀表示当前 TCP 连接出现严重问题,可能需要重新建⽴ TCP 连 接,也可以⽤于拒绝⾮法的报⽂段和拒绝连接请求。 SYN=1 :当 SYN=1 , ACK=0 时,表示当前报⽂段是⼀个连接请求报⽂。当 SYN=1 , ACK=1 时,表示当前报⽂段是⼀个同意建⽴连接的应答报⽂。 FIN=1 :该字段为⼀表示此报⽂段是⼀个释放连接的请求报⽂

RTT

表示发送端发送数据到接收到对端数据所需的往返时间

ARQ协议

ARQ 协议也就是超时重传机制。通过确认和超时机制保证了数据的正确送达, ARQ 协议包含停⽌等待 ARQ 和连续 ARQ 两种协议。

  • 停止等待:

只要 A 向 B 发送⼀段报⽂,都要停⽌发送并启动⼀个定时器,等待对端回应, 在定时器时间内接收到对端应答就取消定时器并发送下⼀段报⽂。

超过定时器设定的时间就会再次发送丢失的数据直到对端响应,所以需要每次都备份发送的数据。即使报⽂正常的传输到对端,也可能出现在传输过程中报⽂出错的问题。这时候对端会抛 弃该报⽂并等待 A 端重传。⼀般定时器设定的时间都会⼤于⼀个 RTT 的平均时间

  • 连续确认(流量控制):

在连续 ARQ 中,发送端拥有⼀个发送窗⼝(发送端窗⼝包含已发送但未收到应答的数据和可以发送但是未发送的数据。发送端窗⼝是由接收窗⼝剩余大小决定的,接收方会把当前接收窗⼝的剩余⼤⼩写⼊应答报⽂,发送端收到应答后根据该值和当前⽹络拥塞情况设置发送窗⼝的⼤⼩,所以发送窗口的⼤⼩是不断变化的。),可以在没有收到应答的情况下持续发送窗⼝内的数据,这样相⽐停⽌等待 ARQ 协议来说减少了等待时间,提高了效率。接收端会持续不断收到报⽂,通过累计确认,可以在收到多个 报⽂以后统⼀回复⼀个应答报⽂。

报⽂中的 ACK 标志位可以⽤来告诉发送端 这个序号之前的数据已经全部接收到了,下次请发送这个序号后的数据。 但是累计确认也有⼀个弊端。在连续接收报⽂时,可能会遇到接收到序号 5 的 报⽂后,并未接收到序号 6 的报⽂,然⽽序号 7 以后的报⽂已经接收。遇到这 种情况时,ACK 只能回复 6,这样就会造成发送端重复发送数据的情况

拥塞处理

拥塞处理和流量控制不同,后者是作⽤于接收⽅,保证接收⽅来得及接受数据。⽽前者是 作⽤于⽹络,防⽌过多的数据拥塞⽹络,避免出现⽹络负载过⼤的情况。拥塞处理包括了四个算法,分别为:慢开始,拥塞避免,快速重传,快速恢复

  • 慢开始

传输开始时将发送窗⼝慢慢指数级扩⼤,从⽽ 避免⼀开始就传输⼤量数据导致⽹络拥塞。

连接初始设置拥塞窗⼝(Congestion Window) 为 1 MSS (⼀个分段的最⼤数据量) 每过⼀个 RTT 就将窗⼝⼤⼩乘⼆ 指数级增⻓肯定不能没有限制的,所以有⼀个阈值限制,当窗⼝⼤⼩⼤于阈值时就会启动拥塞避免算法。

  • 拥塞避免

每过⼀个 RTT 窗⼝⼤⼩只加⼀,这样能够避免指数级增⻓导 致⽹络拥塞,慢慢将⼤⼩调整到最佳值。 在传输过程中可能定时器超时的情况,这时候 TCP 会认为⽹络拥塞了,会⻢上进⾏以下 步骤:

  1. 将阈值设为当前拥塞窗⼝的⼀半
  2. 将拥塞窗⼝设为 1 MSS
  3. 启动拥塞避免算法
  • 快重传

⼀旦接收端收到的报⽂出现失序的情况,接 收端只会回复最后⼀个顺序正确的报⽂序号。如果发送端收到三个重复的ACK ,⽆需等待定时器超时而是直接启动快速重传算法。

TCP Taho 实现:将阈值设为当前拥塞窗⼝的⼀半 将拥塞窗⼝设为 1 MSS 重新开始慢开始算法 TCP Reno 实现:拥塞窗⼝减半 将阈值设为当前拥塞窗⼝进⼊快恢复阶段(重发对端需要的包,⼀旦收到⼀个新的 ACK 答复就退出该阶段)

状态机

三次握手

总结:

  • 客户端发送⼀个TCP的SYN=1,Seq=X的包到服务器端⼝
  • 服务器发回SYN=1, ACK=X+1, Seq=Y的响应包
  • 客户端发送ACK=Y+1, Seq=Z
  1. 起初,两端都为 CLOSED 状态。在通信开始前,双⽅都会创建 TCB。服务器创建完 TCB 后遍进⼊ LISTEN 状态,此时开始等待客户端发送数据
  2. 第一次握手,客户端向服务器发送一个 SYN 连接请求报文段,报文段的首部中 SYN 标志位置为 1,序号字段是一个任选的 随机数。它代表的是客户端数据的初始序号。
  3. 第二次握手,服务器端接收到客户端发送的 SYN 连接请求报文段后,服务器首先会为该连接分配 TCP 缓存和变量,然后向 客户端发送 SYN ACK 报文段,报文段的首部中 SYN 和 ACK 标志位都被置为 1,代表这是一个对 SYN 连接请求的确认,同时序号字段是服务器端产生的一个任选的随机数,它代表的是服务器端数据的初始序号。确认号字段为客户端发送的序号加一。
  4. 第三次握手,客户端接收到服务器的肯定应答后,它也会为这次 TCP 连接分配缓存和变量,同时向服务器端发送一个对服务 器端的报文段的确认。第三次握手可以在报文段中携带数据(为了防止:客户端发送了⼀个连接请求 A,但是因为⽹络原因造成了 超时,这时 TCP 会启动超时重传的机制再次发送⼀个连接请求 B。此时请求顺利到达服务端,服务端应答完就建⽴了请求。如果连接请求 A 在两端关闭后终 于抵达了服务端,那么这时服务端会认为客户端⼜需要建⽴ TCP 连接)
四次挥手

总结:

  • 主动⽅发送Fin=1, Ack=Z, Seq= X报⽂
  • 被动⽅发送ACK=X+1, Seq=Z报⽂
  • 被动⽅发送Fin=1, ACK=X, Seq=Y报⽂
  • 主动⽅发送ACK=Y, Seq=X报⽂
  1. 第一次挥手,客户端认为没有数据要再发送给服务器端,它就向服务器发送一个 FIN 报文段,申请断开客户端到服务器端的 连接。发送后客户端进入 FIN_WAIT_1 状态。
  2. 第二次挥手,服务器端接收到客户端释放连接的请求后,向客户端发送一个确认报文段,表示已经接收到了客户端释放连接的 请求,以后不再接收客户端发送过来的数据。但是因为连接是全双工的,所以此时,服务器端还可以向客户端发送数据。服务 器端进入 CLOSE_WAIT 状态。客户端收到确认后,进入 FIN_WAIT_2 状态。
  3. 第三次挥手,服务器端发送完所有数据后,向客户端发送 FIN 报文段,申请断开服务器端到客户端的连接。发送后进入 LAS T_ACK 状态。
  4. 第四次挥⼿:A 收到释放请求后,向 B 发送确认应答,此时A进⼊TIME-WAIT 状态。该状态会持续2MSL(最⼤段⽣存期,指报⽂段在⽹络中⽣存的时间,超时会被抛弃) 时间,若该时间段内没有 B 的重发请求的话,就进⼊ CLOSED 状态。当 B 收到确认应答后,也便进⼊CLOSED 状态。
为什么 A 要进⼊ TIME-WAIT 状态,等待 2MSL 时间后才进⼊ CLOSED 状态?

为了保证 B 能收到 A 的确认应答。若 A 发完确认应答后直接进⼊ CLOSED 状态,如果确认应答因为⽹络问题⼀直没有到达,那么会造成 B 不能正常关闭

原码补码反码

  • 原码是计算机追踪二进制的定点表示方法,最高位表示符号位,其余位表示数值位,不能够参加运算
  • 在计算机中使用补码来表示负数的原因是,这样可以将加法运算扩展到所有的数值计算上,因此在数字电路中我们只需要考虑加法器的设计就行了,而不用再为减法设置新的数字电路。

进程与线程

  • 进程描述了 CPU 在运⾏指令及加载和保存上下⽂所需的时间,放在应⽤上来说就代表了⼀个程序。
  • 线程是进程中的更⼩单位,描述了执⾏⼀段指令所需的时间

进程间通信的方式

  1. 管道通信
  2. 消息队列通信
  3. 信号量通信
  4. 信号通信
  5. 共享内存通信
  6. 套接字通信