网络知识重点总结

五层协议

  • 应用层: 为特定的应用传输数据. HTTP, SMTP, DNS
  • 传输层: 实现进程到进程之间的通信. TCP/UDP 协议
  • 网络层: 实现主机到主机之间的通信. IP, ICMP, ARP, OSPF协议.
  • 链路层: 为同一链路的主机提供服务. PPP协议, MAC协议
  • 物理层: 在传输媒体上传输比特流, 尽可能为数据链路层屏蔽不同通信设备的差异. RJ45, IEEE802.3协议.

MTU和路径MTU

  • MTU: 链路层数据帧能携带的最大的数据量(不包含链路层头部), 例如以太网限制有效载荷为1500字节。如果ip需要发送一个数据报, 并且这个数据报比链路层MTU要大, 则ip通过分片将数据包分解为多个较小的ip数据报,使每个分片不超过MTU. 这导致ip头部多次出现, 降低了有效数据占的比例.
  • 路径MTU: 两台主机跨越多个网络通信时, 每个链路可能有不同大小的MTU, 其中最小的称为路径MTU.

TCP

TCP特点

  • 面向连接, 提供可靠通信, 支持全双工, 面向字节流, 点对点通信.
  • TCP通过确认和超时重传, 数据分片和排序, 流量控制, 拥塞控制, 数据校验实现可靠传输.
  • 一个TCP套接字是由一个四元组来标识的: <源地址, 源端口号, 目的地址, 目的端口号>.
  • TCP握手阶段的SYN标志是占据一个序列号的, 而消耗了序列号就意味着SYN也是数据, 就会被可靠传输,即对方会有ACK, 会有超时重传等措施. 而不消耗序列号的ACK不会被保证可靠传输.

TCP处理流程

  • 校验: 包含头部信息, 数据部分, 伪头部(源地址, 目的地址, 0, 协议号, TCP报文长度, 总计12字节).
    如果校验出错, 数据包被丢弃, 接收方可能会回复一个对之前已接受数据包的 ack, 以通知发送方重传此数据包.

TCP流量控制

为了使发送方的发送速率与接收方的处理速率匹配, 通过维护接收窗口来实现, 接收窗口表明了接收方可用的缓存空间大小(字节数).

  • TCP头部的16位窗口字段用于向另一方表明自身接口窗口的大小.
  • 发送方可发送的最大序列号值为: 当前的ACK序列号+窗口大小.
  • UDP不支持流量控制, 当发送方发送数据过快时, 数据包会溢出, 导致数据包丢失.
  • 滑动窗口: 累积确认, 回退N帧.

发送方窗口可以分为以下四个部分,其中已发送未确认部分+即将发送部分就是对方宣告的窗口大小.

  • 已发送, 已确认
  • 已发送, 未确认
  • 即将发送
  • 不能发送

接收方窗口分为3个部分,收到第一部分的数据包是重复的, 会被丢弃; 收到第三部分的数据包查出处理范围,
同样被丢弃. 只有收到第二部分的才会被保存下来, 但是只有收到左边界的数据包, 窗口才会右移.

  • 已接收并确认
  • 接收后将会保存
  • 不能接收

TCP拥塞控制

使发送方的发送速度与网络情况匹配, 这是对发送方发送速度的限制.
发送方通过超时, ack来感知网络的变化, 通过窗口大小来控制发送速度.

1.慢启动
  • 当一个新的TCP连接建立或超时时, 执行慢启动. 慢启动指数地增长窗口大小, 每收到一个 ack 就将窗口乘以 2.
  • 如果发生了超时, 将阈值设为当前窗口的一半, 窗口大小设为1, TCP重新进入慢启动状态.
  • 如果窗口大于等于阈值, TCP进入拥塞避免状态.
  • 如果收到 3 个重复的 ack, 表明发生了丢包, 进入快速恢复阶段.

连接建立时的窗口大小可以设定.

2.拥塞避免
  • 线性地增长窗口, 每收到一个 ack 就将窗口加 1.
  • 如果发生了超时, 将阈值设为当前窗口的一半, 窗口大小设为1, TCP重新进入慢启动状态.
  • 如果收到 3 个重复的 ack, 表明发生了丢包, 进入快速恢复阶段.
3.快速恢复
  • 先将阈值设为当前窗口的一半, 再将窗口设为 阈值 + 3MSS, 然后重传丢失的数据包.
  • 如果收到了期望的 ack, 就进入拥塞避免状态, 继续线性地增加窗口大小.
  • 如果发生了超时, 就进入慢启动状态.

旧的实现采用Tahoe算法, 当遇到丢包时, 无论是超时还是重复ACK导致的, 到进入慢启动状态.
后来改为Reno算法, 区分了这两种丢包, 分别进入慢启动和快速恢复状态.

更新的实现采用了NewReno算法, Reno算法在有多个数据包发生丢失时的表现不好.
在第一次收到ACK后, 退出快速恢复, 然后又接收到重复ACK, 再次进行快速恢复. 这个过程会重复多次, 降低了效率.
NewReno算法记录传输窗口的最高序列号(即恢复点), 当发生拥塞避免时, 记录之前发送数据包的最高序列号,
只有当接收到的序列号不小于恢复点的ACK, 才会停止快速恢复阶段.

更复杂的算法是选择确认(SACK), 利用TCP头部的可选项来记录丢失的序列号, 并且要在握手阶段指出是否支持SACK.
利用ack数据包前20字节的ACK序列号和option部分的序列号, 就可以确定丢失的数据.
option部分的序列号是成对出现的, 表示了已接受到数据的范围, 可以有多个序列对.
因为序列对占8个字节, option部分不超过40字节, 因此最多有4个序列对, 实际中由于其他选项占用一般最多只有3对.
设序列对为 (seq1, seq2), (seq3, seq4), (seq5, seq6), ack序列号为 seq0. 那么缺失的序列为: [seq0, seq1), [seq2, seq3), [seq4, seq5)[seq0,seq1),[seq2,seq3),[seq4,seq5).
有一点需要注意, 为了防止之前的SACK丢失, SACK会尽量包含之前的(最近的)SACK信息.

累积确认

  • 主要用于交互式数据传输的情况.(如ssh)
  • 当收到数据时, 并不立即回复 ack, 而是等待一段时间, 尽可能使得 ack 能和这个方向上的数据一起发送.

Nagle算法

是为了处理这样的情况: 大量的小数据包有效数据占比太少, 浪费了带宽. 例如用于交互式数据传输的情况(如ssh)

规定当存在没有被确认的数据包时, 过小的数据包不能被发送, 直到所有的数据都被确认.
并且确认之后, 需要将这些小数据整合到一个数据包发送.

三次握手

三次握手的过程
  1. 客户端发送 syn 数据包, 设置序列号(n).(由于设置了 SYN 字段, 虽然数据项为空, 仍然消耗一个序列号, 所以服务端的 ack 会加一)
  2. 服务端接收到 syn 数据包后, 发送 syn&ack 数据包给客户端, 设置序列号(m), ack序列号(n+1).
  3. 客户端收到 syn&ack 数据包后, 发送 ack 数据包给服务端, 设置序列号(n+1), ack序列号(m+1).
三次握手为了解决哪些问题
  1. 交换双方的序列号.
  2. 当客户端的 syn 数据包长经过很长时间才到达服务端, 而此时客户端认为此数据包丢失时, 服务器会响应此数据包,客户端需要第三次握手来正确处理他. 例如发送RST. 如果客户端置之不理, 会导致服务端长期处于等待/重传状态.

四次挥手

四次挥手的过程

对于主动关闭一方:

  • 发送 FIN, 进入 FIN_WAIT_1.
  • 收到 ACK, 进入 FIN_WAIT_2.
  • 收到 FIN, 回复 ACK, 进入 TIME_WAIT/2MSL.
  • 2MSL时间之后, 进入 CLOSED.

对于被动关闭一方:

  • 收到 FIN, 回复 ACK, 进入 CLOSE_WAIT.
  • 发送 FIN, 进入 LAST_ACK.
  • 收到 ACK, 进入 CLOSED.
四次挥手的原因

TCP是全双工模式, 两次挥手只会释放一个方向的连接, 释放双向的连接需要四次. 当一方释放连接时,
另一方可能还有数据未传输完, 因此两次连接释放不能合并.

2MSL

当执行主动关闭的一方收到被动关闭一方的 FIN 数据包时, 回复 ACK 数据包, 就进入 TIME_WAIT 状态,
并至少持续 2MSL 时间. (MSL 表示报文在网络中最长的生存时间)

在 TIME-WAIT 状态, 当:

  • 接收到 FIN 数据包时, 会再次回复 ACK.
  • 期间端口号不能被再次使用.

这是为了解决两种异常情况:

  • 防止被动关闭的一方没有收到回复的ack, 这样 FIN 就会再次发送, 主动关闭方收到后再次回复 ack,并重新进入 TIME_WAIT 状态.
  • 保证此次连接的所有数据包都消失或被处理, 不会出现在新的连接中. 如果过快建立新的连接,可能本次连接的数据包因为延迟, 出现在新的连接之中.

TCP 中的 Timer

注意一点, 下面说得timer并不是超时超时重传中用到的timer. 而且有的timer定义的是次数, 但是实际上协议栈并不仅仅只考虑次数,会结合时间来看.

1.connection-establishment timer

在建立tcp连接时起作用, 有两个:

  • tcp_syn_retries: client发送完 SYN 后, 进入 SYN_SENT 状态, 等待服务端回复 SYN+ACK.
  • tcp_synack_retries: server 收到 SYN, 回复完 SYN+ACK 后, 进入 SYN_RCVD 状态, 等待client的 ACK.

在上面的两个等待中, 如果发生超时, 就会重传数据包. 但是不能无限制的重传, 因此分别定义了 tcp_syn_retries 和 tcp_synack_retries, 二者表示重传的次数, 间接定义了最长的等待时间.

2.retransmission timer

三次握手成功后, 连接建立, 客户端就可以发送数据包, 再等待服务端的ACK. 如果在指定时间内没有收到ACK,
就会重传, 直到重传了指定的次数才会放弃. 这里存在两个timer, 都是重传次数:

  • tcp_retries1: 如果重传超过这个值, 就会更新路由缓存, 然后继续重传.
  • tcp_retries2: 如果重传超过这个值, 直接终止重传.
3.delayed ack timer

一方收到数据包后, 可以等待一定时间, 等其他数据包达到后, 一起返回ACK. 这段等待时间为 delayed ack timer,
一般最长为 200ms.

4.persist timer

设想这样的情况:当server缓存已满, 就会通知client自身窗口为0, 这导致client停止发送数据.
当server出现空余空间后, 就需要通知client新的窗口大小, 但是这个通知不会携带任何数据,
所以client不会回复ack, 因此即使这个数据包丢失了server也不会感知到(ACKs are not acknowledged, only data is acknowledged).
如果此通告client没有接收到, 也就不会继续发送数据包. 因此需要一种机制来解决此问题:

client知道server窗口为0后, 当有数据要发送时, 虽然知道不应该发送数据, 也会在一段时间后尝试发送一个字节.
这段时间就是 persist timer.

5.keepalive timer

当启用tcp socket的SO_KEEPALIVE option时, 即使双方没有数据发送, 也会保持连接. 保持连接的方式是发送 probe segment.
当连接经过一段时间(tcp_keepalive_time)没有数据包传送后, tcp就会主动发送 probe segment, 强制对方回应. 并且每隔一段时间(tcp_keepalive_intvl)就会发送一个probe segment,如果对方没有回应, 在连续发送了一定数量(tcp_keepalive_probes)后, 主机就会放弃, 并终止连接.

6.fin_wait_2 timer

client主动终止连接(发送FIN), 并收到ACK后, 就进入 fin_wait_2状态. 此时不能继续发送数据, 如果server一直不发送FIN, client就会一直处于此状态, 导致资源无法释放. 因此定义了 tcp_fin_timeout(单位是秒),当处于fin_wait_2的时间超过这个时间时, 就会终止连接.

7.time_wait timer

即2MSL, 其作用是为了回复的ack丢失时, 能收到重传的FIN并继续返回ack, 另一个是保证当前连接的数据包完全消失.

UDP

UDP特点

  • 无连接(没有握手过程), 尽最大努力交付, 面向报文, 首部只有8个字节, 支持多对多通信.
  • 一个UDP套接字是由一个二元组来标识的: <目的地址, 目的端口号>.
  • UDP提供端到端的校验, 接收方会根据头部的检验和判断数据包是否发生错误, 但是不能恢复错误, 只能交由上层应用来处理.

检验和覆盖了UDP头部, UDP数据, 伪头部, 运算单位是2字节(16位). 伪头部指的是:

  • 源地址ip(4字节)
  • 目的地址ip(4字节)
  • 0(1字节), 协议号(1字节), UDP长度(2字节)

之所以加上伪头部是为了检验数据是否到达了正确的目的地.

UDP处理流程

IP

IP数据包头部包含20个字节加上可选部分.

  • 校验和: 只包含IP数据包的头部. 每台路由器收到ip数据包后都会利用检验和进行校验, 如果出错, 就会将数据包丢弃.
    否则会重新计算校验和. 因为IP头部信息是在不断变化的, 例如TTL.
  • ip分片: 上层的数据报过大时, 会进行分片, 以满足接口的MTU限制. ip分片直到到达运输层目的地时才会在网络层重组.
    如果一个报文的分片丢失, 整个报文会被丢弃, 不会交给运输层. 之所以在目的地才重组, 原因有二:
    • 在网络中不进行重组能减轻路由转发的负担.
    • 同一数据报的不同分片可能经由不同的路由到达目的地, 因此在中间重组是不可能的.

路由协议-内部网关协议(用于AS内部)

RIP协议

RIP协议使用两个子网之间经过的子网数来作为距离, 相邻子网距离为1, 称为跳数.

相邻路由器交换路由选择信息, 其中包含了路由器自身已知的到其他路由器的跳数.
路由器根据接收到的路由选择信息更新转发表. 转发表包含目的子网, 下一跳路由, 到目的子网的跳数.

OSPF协议

工作在网络层, 依赖IP.

和全局的所有路由器交换信息, 用得到的信息构建链路状态数据库, 用Dijkstra算法计算最短路径, 生成路由表.
详细过程为:

  1. 路由器和直接相连的路由器交互, 发送Hello报文, 建立邻居关系.
  2. 路由器根据和直接相连的路由器间的链路构建链路状态广播(LSA), LSA记录了所有相邻的路由器及其表示, 链路类型, 带宽等.
  3. 路由器将自己的LSA发送给所有邻居, 接收到LSA的路由器也会将LSA发送给其他邻居节点.(组播)
    最终一个区域中的所有路由器都可以得到区域的完整拓扑, 并基于此来构建链路状态数据库.
  4. 根据链路状态数据库, 路由器采用Dijkstra算法计算出一棵以自己为根的最短路径树, 并生成路由表.

OSPF运行在一个自治域(AS) 中, 并允许将一个自治域划分为多个区域, 其中必须有一个是骨干域,
其他的称为非骨干域, 每个非骨干域都必须与骨干域相连(直接或间接).
根据路由器接口所在区域的不同, 一个路由器可以有三种角色.

  • 区域内部路由器: 所有接口都在区域之中;
  • 区域边界路由器(ABR): 用于连接非骨干区域和骨干区域, 即有的接口处于非骨干区域, 有的接口处于骨干区域,
    前者可以有多个处于不同非骨干区域的.
  • 自治域边界路由器(ASBR): 用于连接当前AS与其他AS.

IS-IS协议

工作在网络层.

与OSPF的不同点:

  • 虽然将AS划分为多个区域, 但是区域的边界在链路, OSPF的区域边界在区域边界路由器(ABR).
    进而OSPF中每条链路只属于一个区域, 而IS-IS中每台路由器只属于一个区域.
  • 在区域内采用最短路径优先来计算路径, 在区域间用距离向量来计算路径.

IS-IS协议同样将AS划分为多个区域, 区域之间通过链路(OSPF是路由器)相连.
IS-IS中路由器分为三种:

  • level 1 路由器: 作用于区域内, 没有直接连接到其他区域的链路. 负责收集区域内的路径信息.
  • level 1-2 路由器: 有直接连接到其他区域的链路, 负责收集区域间的路径信息.
  • level 2 路由器: 作用于区域外, 负责收集区域内和区域间的路径信息. 类似OSPF中的ABR.(?)

路由协议-外部网关协议(用于AS之间)

BGP协议

BGP路由基于前缀, 采用路由聚合策略, AS之间通过网关路由器交换信息.

路由转发过程

  • 路由表包含下面的信息: 目的ip, 子网掩码, 下一条ip, 标志, 接口等. 使用最长前缀匹配算法来寻找下一跳.
  • 最长前缀匹配算法: 在表中搜索所有条目, 记录掩码运算后匹配的条目, 并选择最匹配(即掩码最长)的条目进行转发.
    如果不存在匹配条目, 就返回ICMP报文, 指明"主机不可达". 存在有多个最匹配条目的情况, 此时可以直接选择第一个,
    也可以利用此来实现负载均衡, 拆分流量等.

DHCP协议

使得主机可以自动获取ip地址. 步骤如下:

  1. DHCP服务器发现(DHCPDISCOVER): 新到主机广播DHCP发现报文(ip数据包), 并且设置源地址为 0.0.0.0, 并设置 xid(标记此次会话).
  2. DHCP服务器提供(DHCPOFFER): 收到DHCP发现报文的DHCP服务器会广播回复DHCP提供报文, 其中包含对应 xid,
    提供给客户的ip地址, 子网掩码, ip地址租用期.
  3. DHCP请求(DHCPREQUEST): 新到的主机从若干个DHCP提供报文提供的ip地址中挑选一个, 并对该DHCP服务器发送一个DHCP请求报文,回显配置参数.
  4. DHCP ACK(DHCPACK): 服务器用DHCP ACK报文对请求报文进行响应, 证实客户要求的参数.

客户一旦收到 ACK, 交互就完成了. 并且还有机制使得用户可以延长租约.

NAT协议

路由器保存一张NAT转换表, 记录局域网客户 ip:port 到广域网的 ip:port 的映射, 对向外的报文替换源地址和端口,
对向内的报文替换目的地址和端口. 注意这还需要重新计算校验码.

ICMP协议

建立在IP协议之上.

ping程序基于ICMP协议, 探测方发送一个 ICMP 请求数据包, 目的端如果没有屏蔽ICMP报文, 就会回复一个ICMP应答数据包.

traceroute基于TTL的规则, 可以采用ICMP实现, 也可以采用UDP实现. 下面是基于UDP的实现介绍.
首先设置TTL=1(在IP协议的头部), 这样到第一跳时, TTL减一之后就为0, 路由器就会返回不可达错误.
其后不断使TTL加 1, 直到到达指定目的地. 这样就能得到主机之间的路径.
并且, 程序使用的端口号大于30000, 到达目的主机后, 由于不存在这个端口, 同样会产生不可达错误,
并返回ICMP不可达给源主机. 这样源主机就知道到达了目的主机.
在基于ICMP的实现中中间路径的获取同样基于TTL的原理, 确认到达目的则是依据目的的ICMP回复.

HTTP协议

特点
http是无状态协议, 不保存关于客户的任何信息.
可以采用持续连接和非持续连接两种方式. http默认采用带流水线的持续连接.

  • 持续连接: 每一次http请求/响应都经过相同的tcp连接. 一般如果一条tcp连接经过一定时间(可配置)仍未使用,
    http服务器就会关闭该链接.
  • 非持续连接: 每一次http请求/响应经过不同的tcp连接.

http的方法:

  • get: 用于获取信息, 是安全, 幂等的. 即不会对修改数据, 重复多次得到的结果相同. 幂等.
  • head: 用于向服务请求某项资源, 服务器会按照get来处理, 但是不返回资源内容, 用户查看服务器性能. 幂等.
  • post: 向服务器提交数据, 会导致在服务器上创建/修改资源. 非幂等.
  • put: 向服务器提交数据, 如果已存在就会覆盖原有数据. 幂等.
  • delete: 请求删除服务器的资源, 不存在则会忽略请求. 幂等.
  • option: 查看指定资源支持的方法(如get, delete等), 用于检查客户端是否具有某项权限. 常用于测试服务器.
  • trace: 请求服务器回显收到的请求信息, 用于测试服务器.

下面介绍 post 和 put 的区别. 二者相同点是都需要指定一个 URI, 包含一个资源实体, 用于向服务端提交资源.

  • 对于 post, URI被作为目录, 资源会被放置在该目录下(要求目录已经存在, 否则会返回错误), 资源的名字由服务端决定.
  • 对于 put, URI 就是资源在服务端的完整路径.

因此, 当多次调用同一 post 方法时, 同一资源会在同一目录下保存多份, 每个资源被分配不同的名字, 因此 post 不是幂等的.
而多次调用同一 put 时, 新的请求的资源实体会覆盖已保存资源(虽然两个资源是相同的). 因此 put 是幂等的.

条件Get: 用于节省带宽, 降低负载. 用户发起get请求时, 发现本地有资源的缓存, 就设置 If-Modified-Since 字段,
后面指明时间, 如果服务器发现该时间之后对应资源没有改变, 就告知请求者, 并且不返回资源, 请求者就可以直接加载本地的资源.

DNS协议

dns协议的作用:

  • 域名解析
  • 主机别名
  • 邮件服务器别名
  • 负载均衡

dns服务器层次:

  • 根域名服务器
  • 顶级域服务器
  • 权威dns服务器
  • 本地dns服务器

dns 解析过程分为递归查询和迭代查询两种, 实际中是二者结合使用, 从终端用户看来是递归查询,
而根域名服务器和顶级域服务器都是迭代查询.

  • 递归查询: 当dns服务器无法获得ip时, 将请求转发到下一级, 再将下一级的请求转发给请求者.
  • 迭代查询: 由dns服务器先向根域名服务器发起查询, 根据回复, dns服务器再向下一级dns服务器发起查询, 直到获得ip.

 本地dns服务器可以缓存常用主机名到ip的映射, 以加快dns解析. 但是缓存不能太长, 因为 dns 的映射不是永久的.

在浏览器中输入URL时的解析过程:

  • 浏览器检查自身的DNS缓存, 没有则调用对应接***由操作系统进行解析.
  • 操作系统先检查hosts文件是否有该映射, 有则返回.
  • 向本地指定的dns服务器发起查询, 等待返回.
  • 本地dns服务器检查缓存和本地记录, 如果没有就进行递归查询.

HTTPS协议

握手过程:

  • Client Hello: 客户端向服务器发送消息. 其中包含一个客户端生成的随机数(val1).
  • Server Hello: 服务器相应客户端的请求. 其中包含一个服务器生成的随机数(val2)和服务器的证书.
  • 客户端请求: 客户端验证证书之后, 从证书中取出服务器的公钥, 并回复服务器.
  • 其中包含一个用公钥加密过的随机数(val3), 并通知服务端握手结束.
  • 服务器回应: 服务器通过私钥解密随机数(val3), 并用三个随机数生成一个对称秘钥, 之后的数据都会有此密钥加密,
    并通知握手结束.(此时客户端也知道了三个随机数, 也就可以生成对称秘钥)

Cookie和Session
用于识别用户的身份,Cookie保存在客户端,Session保存在服务器端。

ARP协议

用于发现子网中主机的MAC地址. 过程为:

  • 主机广播请求指定 ip 的 mac 地址, 该请求被封装为一个链路层数据帧.
  • 子网上的主机收到后, 检查自身ip地址是否等于请求中的ip地址, 若等于, 就向请求主机发送回复.
  • 主机收到回复后, 更新arp表.

常见问题

访问一个网址的过程:

  • dns解析.
  • 发起TCP连接.
  • 向指定服务器发起HTTP请求. 服务器可能会进行反向代理, 将请求转发到其他服务器进行处理.
  • 浏览器获取到返回结果后, 进行渲染. 如果是非持续连接, 就会关闭TCP连接.
  • 某些资源可能需要再次发起HTTP请求, 过程同上.
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页