网络模型

分区及图片  设备图

七层模型

  1. 应用层——–电脑的各种数据
  2. 表示层 ——– 处理用户信息的表示问题,如编码、数据格式转换和加密解密
  3. 会话层——–会话管理、会话流量控制、寻址、寻址
  4. 传输层——–各种协议(TCP/IP中的TCP协议、Novell网络中的SPX协议和微软的NetBIOS/NetBEUI协议。 )
  5. 网络层——–路由器(通过路由选择算法,为报文或分组通过通信子网选择最适当的路径)
  6. 数据链路层—-交换机/网桥(负责建立和管理节点间的链路,通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路)
  7. 物理层

五层模型

  1. 应用层
  2. 传输层
  3. 网络层
  4. 数据链路层
  5. 物理层

数据格式

  1. 数据二进制字节流 (Byte) : 物理层传输
  2. 数据帧(Frame):是一种信息单位,它的起始点和目的点都是数据链路层
  3. 数据包(Packet):也是一种信息单位,它的起始和目的地是网络层
  4. 数据报(Datagram):通常是指起始点和目的地都使用无连接网络服务的的网络层的信息单元。
  5. 数据段(Segment):通常是指起始点和目的地都是传输层的信息单元。
  6. 报文 (message) :报文包含了应用层的完整的数据信息。

HTTP

超文本含义

  • 超越了普通文本的文本,它是文字、图片、视频等的混合体,最关键有超链接,能从 一个超文本跳转到另外一个超文本

http5新特性

EventStream

  • 本质上就是hold住http连接
  • 只能服务端给客户端发,不是双向的
  • 文本协议
  • 参考

HTTPS

  • 解决安全性问题
  • 参考TLS

状态码分类

http2.0/3.0

1. 头部压缩

  • 静态编码成为哈夫曼编码,压缩请求头

2. 二进制格式

  • 一条 HTTP 响应,划分成了两类帧(头部和消息体)来传输,并且采用二进制来编码。

3. 数据流并发传输

  • 通过一个TCP发送多个请求
  • 一个TCP包含多个stream(这里是类似http1.1的多个tcp请求),每个stream自身保持有序

4. 服务器推送(主动推送css等文件)

  • 3.0改成udp连接了,太离谱了

优化方法

  1. 缓存减少请求
  2. 合并请求
  3. 按需访问
  4. 压缩算法

TCP

  • TCP 连接是由四元组唯一确认的,这个四元组就是:本机IP, 本机端口, 对端IP, 对端端口

定义

  • TCP是一种“可靠的、基于连接的流协议”,其中,“可靠”的意思是:(物理网络 正常的前提下)TCP保证用户数据的完整性。完整性本身就包含了顺序等方面的要求。而“流”的意思则是:数据是以字节为单位的,不存在分包概念。
  • 会出现丢包现象,但是会自己进行重试,不让用户进行感知

报文格式

三次握手

  • 第三次握手是可以携带数据的,前两次握手是不可以携带数据的

QA

  1. 为什么三次握手才可以初始化 Socket、序列号和窗口大小并建立 TCP 连接
  • 三次握手才可以阻止重复历史连接的初始化(主要原因),如果只有两次的话,可能网络中存在历史的syn包,然后服务端接受之后发ack成功,实际上并没有成功(使用RES保文方法)
  • 三次握手才可以同步双方的初始序列号
  • 三次握手才可以避免资源浪费
  1. 什么是 SYN 攻击?如何避免 SYN 攻击?
  • SYN 攻击方式最直接的表现就会把 TCP 半连接队列打满,这样当 TCP 半连接队列满了,后续再在收到 SYN 报文就会丢弃,导致客户端无法和服务端建立连接。
  • 解决办法
  • 调大 netdev_max_backlog;
  • 增大 TCP 半连接队列;
  • 开启 tcp_syncookies;
  • 减少 SYN+ACK 重传次数

四次挥手

QA

  1. 为什么挥手需要四次?
  • 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
  • 服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
  1. 什么时候可以使用三次连接
  • 「没有数据要发送」并且「开启了 TCP 延迟确认机制」,那么第二和第三次挥手就会合并传输,这样就出现了三次挥手。
  1. 为什么需要 TIME_WAIT 状态?
  • 保证「被动关闭连接」的一方,能被正确的关闭 >如果客户端(主动关闭方)最后一次 ACK 报文(第四次挥手)在网络中丢失了,那么按照 TCP 可靠性原则,服务端(被动关闭方)会重发 FIN 报文。 >假设客户端没有 TIME_WAIT 状态,而是在发完最后一次回 ACK 报文就直接进入 CLOSE 状态,如果该 ACK 报文丢失了,服务端则重传的 FIN 报文,而这时客户端已经进入到关闭状态了,在收到服务端重传的 FIN 报文后,就会回 RST 报文。
  1. 为什么 TIME_WAIT 等待的时间是 2MSL?
**TTL 的值一般是 64,Linux 将 MSL 设置为 30 秒,意味着 Linux 认为数据报文经过 64 个路由器的时间不会超过 30 秒,如果超过了,就认为报文已经消失在网络中了**。

TIME_WAIT 等待 2 倍的 MSL,比较合理的解释是: 网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以**一来一回需要等待 2 倍的时间**。

比如,如果被动关闭方没有收到断开连接的最后的 ACK 报文,就会触发超时重发 `FIN` 报文,另一方接收到 FIN 后,会重发 ACK 给被动关闭方, 一来一去正好 2 个 MSL。

可以看到 **2MSL时长** 这其实是相当于**至少允许报文丢失一次**。比如,若 ACK 在一个 MSL 内丢失,这样被动方重发的 FIN 会在第 2 个 MSL 内到达,TIME_WAIT 状态的连接可以应对。
  1. 出现大量 TIME_WAIT 状态的原因
  • 第一个场景:HTTP 没有使用长连接
  • 第二个场景:HTTP 长连接超时
  • 第三个场景:HTTP 长连接的请求数量达到上限

保活

  • 定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。在 Linux 系统中,最少需要经过 2 小时 11 分 15 秒才可以发现一个「死亡」连接

全连接队列和半连接队列

  • 半连接队列,也称 SYN 队列;
  • 全连接队列,也称 accept 队列;
  • 可以存在多个进程accept同一个端口,然后内核会类似生产者消费者唤醒accept函数(这个accept函数实际上是从全连接队列中获取连接的),三次握手发生在内核,和accept解耦且没有关系

重传机制

RTT和RTO

  • RTT(Round Trip Time):一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值;
  • RTO(Retransmission Time Out):重传超时时间,即从数据发送时刻算起,超过这个时间便执行重传。

超时重传

TCP 会在以下两种情况发生超时重传:

  • 数据包丢失
  • 确认应答丢失

快速重传(FACK算法)

  • 快速重传的工作方式是当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段
  • 因为可能存在乱序情况(不需要重发),因此三次是比较合适的次数
  • 出现不知道缺失了多少的问题

SACK

  • 解决快速重传的问题
  • 通过ack中携带已经收到的序号

ACK延迟确认机制

  • 接收方在收到数据后,并不会立即回复ACK,而是延迟一定时间。一般ACK延迟发送的时间为200ms,但这个200ms并非收到数据后需要延迟的时间。
意义
  1. 合并ack,减少网络占用
  2. 接受放有数据的话顺手发送数据带上ACK

滑动窗口

意义

  • 进行流量控制,通过控制发送方的发送速率达到流量控制的效果,发送方的发送窗口和接受窗口大小不是严格相等,而是大约相等,而且会动态变化
  • 提高丢包容错率,ack某个丢包不影响接受,这个模式就叫累计确认或者累计应答
  • 可以指定窗口大小,窗口大小为无需等待确认应答,而可以继续发送数据的最大值,使得不用漫长等待,提高发送的效率

发送方

接收方

  • 如果在红色区域的数据包会直接丢弃,用于流量控制

问题

  • 会出现死锁问题,当接受窗口大小为0时候,发送方等待接收方ack才能发,接收方如果此时ack丢失,接受方也在等待发送发继续发送(死锁,相互等待)
解决办法
  • 为了解决这个问题,TCP 为每个连接设有一个持续定时器,只要 TCP 连接一方收到对方的零窗口通知,就启动持续计时器。
  • 如果持续计时器超时,就会发送窗口探测 ( Window probe ) 报文,而对方在确认这个探测报文时,给出自己现在的接收窗口大小。 窗口探测

流量控制

  • 通过滑动窗口大小的变化达到动态控制流量
  • 发送方接受到的ack包含接收端窗口的大小(这部分的大小是不去要确认也可以发送的大小)
  • 如果接收端发现自己的缓冲区快满了,就可以通过ack包头中设置减少发送窗口的大小

拥塞控制

  • 通过拥塞窗口大小达到控制,只在发送端存在,控制发送端的发送窗口大小,拥塞窗口 cwnd是发送方维护的一个的状态变量,它会根据网络的拥塞程度动态变化的
  • 此时发送窗口的值是swnd = min(cwnd, rwnd),也就是拥塞窗口和接收窗口中的最小值。

慢启动

  • 一开始窗口大小设置为1,当ack则加倍,直到到达慢启动门限

拥塞避免算法

  • 到慢启动门限之后,每个ack加一,如果出现丢包拥塞,慢启动门限减半

快速重传

  • 对某个报文发出3个ack代表需要,发送端对该报文重发

流量控制和拥塞控制的区别

  • 拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;常用的方法就是:(1)慢开始、拥塞避免(2)快重传、快恢复.
  • 流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。
  • 目的不同:流量控制主要关注发送方和接收方之间的数据传输速率,确保接收方能够处理接收到的数据;而拥塞控制主要关注网络中的拥塞程度,避免网络拥塞和保持网络的稳定性。
  • 控制对象不同:流量控制是在发送方和接收方之间进行控制,通过滑动窗口机制实现;拥塞控制是在网络中进行控制,通过监测网络拥塞程度和调整发送方的数据传输速率实现。
  • 两者都可以控制发送端的发送窗口大小

UDP

报文格式

socket编程

backlog作用

  • TCP 和 UDP 是可以同时绑定同一个端口号的

IP

头部信息

  • 每次传播,TTL和checksums都会改变

ip地址分类

[!important] 127.0.0.1 和 0.0.0.0 区别 通常网络程序bind host的时候 127表示只能通过本地访问(127或者localhost),不接受其他ip访问,0.0.0.0代表接受所有的ip访问

ARP

  • 在传输一个 IP 数据报的时候,确定了源 IP 地址和目标 IP 地址后,就会通过主机「路由表」确定 IP 数据包下一跳。然而,网络层的下一层是数据链路层,所以我们还要知道「下一跳」的 MAC 地址。
  • 由于主机的路由表中可以找到下一跳的 IP 地址,所以可以通过 ARP 协议,求得下一跳的 MAC 地址。
  • 网络层协议

DHCP

  • 通过 DHCP 动态获取 IP 地址
  • 全程都是使用 UDP 广播通信,应用层协议

ICMP

  • ICMP 主要的功能包括:确认 IP 包是否成功送达目标地址、报告发送过程中 IP 包被废弃的原因和改善网络设置等。
  • 网络层协议,一般认为属于IP层协议
  • ping命令使用的协议

ping流程

网卡

  • 网卡是电脑的一个接收信息,转换信息,暂储信息的一个硬件,通常虚拟化,如docker0
  • 同一个网卡下程序可以直接通讯

八股

get和post的区别

  1. post更安全(不会作为url的一部分,不会被缓存、保存在服务器日志、以及浏览器浏览记录中)
  2. post发送的数据更大(get有url长度限制)
  3. post能发送更多的数据类型(get只能发送ASCII字符)
  4. post比get慢
  5. post用于修改和写入数据,get一般用于搜索排序和筛选之类的操作

session,cookie和token区别

  • Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
  • Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
  • Token类似一个令牌,无状态,用户信息都被加密到token中,服务器收到token后解密就可知道是哪个用户。需要开发者手动添加。

有了http为什么还需要rpc

  1. http的报文是明文状态,导致很长,传输效率不够高,相当于不够专业,因此大部分使用类似protobuf压缩,性能更加好
  2. http是一种应用层的协议,而rpc是一种调用方式,有的rpc底层分装的也是http

参考