2. 计算机网络
问题:计算机网络体系结构
OSI 体系结构:官方倡导理论标准。概念清楚、理念完整,但复杂、不实用。
TCP / IP 结构:业界通用实际标准。是 Internet 的核心协议,简化了 OSI。
五层体系结构:融合了OSI 与 TCP / IP的体系结构,是学习计算机网络的基本结构。
物理层
作用:在各种计算机的传输媒体上 透明的传输比特流。硬件设备、传输媒体、通信手段各异,物理层要屏蔽掉这些差异,使物理层上数据链路层感觉不到差异。
功能 4:“机电工龟” 四特性
- 机械特性:接口所有的接线器的尺寸、引脚数量,排列方式。
- 电气特性:各条线路中,信号的电压范围,何种信号表示电压0和1、传输速度、距离。
- 功能特性:某条线上出现的垫平电压的具体含义。
- 规程特性:过程特性。不同功能的事件,出现的顺序。
数据链路层
作用 3:将网络层的 IP 数据报:封装成帧、透明传输、差错检测。
- 封装成帧:在数据前后添加首部和尾部形成帧。比特流上的信息是连续不断的,接收端收到物理层上交的比特流,只要通过首尾标记才能找到数据的开始和结束,准确识别出帧。
- 透明传输:上层的数据不论是何种比特组合,都要正确的传输。
- 差错检测:差错检测和差错纠正。数据链路层有差错检测,帧在某一结点出现错误,及时丢弃,这个无效的帧就不会在剩下的结点中传输,浪费网络资源,降低传输效率。
- 帧定界:若没有封装成帧,没有帧定界,接收端无法准确的在比特流中区分出帧。
功能 4:
- 链路连接建立,管理。
- 帧定界和帧同步。
- 差错控制。
- 透明传输。
网络层
作用 3:
- 将传输层的报文段(UDP)和用户数据报(TCP)封装成 IP 数据报。
- 异构网络互联、路由选择、路由转发。
- 解决 IP 地址和 硬件地址 的映射 / 扩展方式。
问题:说明 IP 地址和硬件地址的区别。
- 区别:物理地址是数据链路层和物理层使用的地址;IP 地址是网络层以及以上使用的地址,是软件实现的逻辑地址。两者用 ARP / RARP 转换。
- 原因:
- 异构。存在各种各样异构的网络,采用不同的硬件地址体系,非常庞大。
- 统一。为了使异构网络能通信,IP 地址屏蔽了 IP 层下的细节,形成整体统一网络。
- ARP。用户只知道 IP 地址就可互相通信,而硬件地址的获取交由 ARP 执行。
传输层
功能:
- 进程间逻辑通信。
- 差错检测。
- 无连接服务和面向连接服务。
- 复用和分用。
- TCP还有:连接管理、流量控制、拥塞控制。
作用:为应用层提供通信服务,是面向通信部分的最高层,用户功能中的最低层。
- 主机 (网络边缘部分) 的协议栈有运输层,路由器 (网络核心部分) 在分组转发时只用下三层。
- 网络层:提供主机到主机的通信。但真正通信的实体是主机的进程,IP 协议只能把分组送到目的主机,还需要运输层的协议把数据交付到应用进程。
- 运输层:提供主机端口到端口到通信,以及相应必须的功能:
应用层
作用:直接为用户的应用进程提供服务。 功能:1.文件传输。2.访问和管理。3.电子邮件服务等协议
问题:计算机网络有哪些协议?
数据链路层协议
PPP:点对点协议,使用广泛
- 不可靠传输,简单,无差错恢复、无序号、无流量控制。
- 面向字节,有差错控制,出现差错直接丢弃
HDLC:高级数据链路控制协议 High-Level Data Link Control
- 面向比特,采用 0 比特插入法。
- 可靠传输,按序传输,有流量控制。
网络层协议
IP:网际协议。使各种异构的物理网络在网络层上看起来是一个统一的网络——IP网。忽略了上层的差异。无连接的数据报传输。
ARP:地址解析协议。
- 把主机或路由器的 IP 地址转换为 物理地址/硬件地址。采用广播的形式,根据目的地址的 IP 地址,获取其硬件地址,然后在数据链路层封装硬件地址,然后传输帧。
RARP:逆向地址解析协议。
- 物理地址转换为 IP 地址。假如一个设备不知道它自己的IP地址,但是知道自己的物理地址,所以要向 Host 主机请求,了解本地局域网的 IP 地址。从而可以给互联网中其他设备发送信息。
ICMP:网际控制报文协议。
- 主机或路由器报告差错和异常的方式,其封装在 IP 数据报中。网络通否?主机可达?路由可用?
- Ping 通过 4 次探寻,测试网络是否可达。可以探寻:目的 IP 地址、发送 / 收到 / 丢失的分组数、往返时间的最小 / 最大 / 平均值。
IGMP:网际组管理协议
- 本局域网管理。本局域网多播路由器,管理本地主机加入 / 退出某多播组。
OSPF:链路状态协议
- 基于 IP 数据报的 路由选择协议。每当网络发生拓扑变化,就采用洪范法通知本自治系统内的所有路由器。使全自治系统范围内的链路数据库保持一致。
应用层 TCP 协议:
BGP:边界网关协议
- 一种基于路径-向量的路由选择协议。主要目的是在自治系统内找到一条可达边界的路由,而非最佳路由。
SSH:Secure Shell,安全外壳协议
- 安全的远程登录。通过对密码进行加密传输验证,在不安全的网络中对网络服务提供安全的传输环境,实现ssh客户端和ssh服务器端的连接。
Telnet:Internet远程登录服务的标准协议
- 常用与远程登录控制 Web 服务器,但不如 SSH 安全。
HTTP:超文本传输协议
- 互联网中,浏览器实现点对点传输的主要通讯方式。
SMTP + POP3:简单邮件传输协议
- 发件人主机通过 SMTP 发送到发件服务器、在互联网传播通过 SMTP 到收件人服务器、通过 POP3 到收件人主机。
FTP:文本传输协议
- 相比 TFTP,是可靠的文件传输。
应用层 UDP 协议:
QUIC:Quick UDP Internet Connection。
- HTTP/3 的主要协议,基于 UDP,集成 TCP + HTTP/2 的多路复用 + TLS 等功能。
TFTP:简单文件传输协议
- 文件传输,不可靠交付。
SNMP:简单网络管理协议
- 网络管理
DNS:域名系统局。
- 域网的 IP 地址配置,通过网址获取 IP 域名的协议。
RIP:距离-向量算法
- 最简单的路由选择协议,通过记录到指定路由器的跳数,构建路由表。
DHCP:动态主机配置协议。
- 采用广播的方式,给本地局域网中的主机动态配置 IP 地址。
其他专用协议:IP 电话、流式多媒体通信(音视频/直播)。
第五章 传输层
传输层的主要知识点:UDP、TCP、停止等待协议、拥塞控制、可靠传输、滑动窗口、累计确认、端口。
问题:传输层的作用
传输层主要解决进程间的通信问题,为应用层提供通信服务。只有主机的协议中才有运输层,路由器等转发设备只用到下三层(物理、数据链路、网络)。
- 进程间通信。两个主机进行通信,就是两个主机的应用进程相互通信,端到端的通信是进程的通信。网络层为主机之间提供逻辑通信,运输层为应用进程之间提供端到端的逻辑通信。
- 复用/分用。在运行时,一个主机有 n 个进程,同时也可能有 n 个进有通信需求。复用:所有的通信进程,都使用运输层协议传输数据。分用:运输层接收到数据后,在运输层剥去报文首部后,能够把这些数据正确交付目的应用进程。
- 差错检测。运输层可对接受的报文进行差错检测(TCP 协议)。而网络层的 IP 数据报只检测首部是否出现差错,而不检查数据部分。
- 两种协议。运输层根据需求,提供了面向连接的 TCP 和无连接的 UDP 两种协议。
- 用户数据报协议 UDP(User Datagram Protocol),UDP 用户数据报。
- 传输控制协议 TCP(Transmission Control Protocol),TCP 报文段。
- 逻辑通信。运输层向高层屏蔽了下面网络的实现细节(网络拓扑、路由选择协议等),它使应用进程看见的就是好想两个运输层实体之间有一条端到端的逻辑通信信道,是一条全双工的可靠信道。
问题:端口号
TCP/IP 运输层用 16 位端口号来标志端口。
- 服务器端使用的端口号:
- 熟知端口号 / 系统端口号:0~1023。上文中常用的应用层协议,就是用这些熟知端口号进行通信,如 FTP 21,DNS 53,HTTP 80。
- 登记端口号:1024~49151。需要在 IANA 登记,防止重复。
- 客户端使用的端口号:49152~65535。客户端进程可以短暂使用的端口号。
问题:UDP 主要特点
用户数据报协议 UDP(User Datagram Protocol),UDP 用户数据报。
UDP 其实只是在 IP 的数据报服务上,额外增加了端口的功能 + 差错检测的功能。
- 无连接。发送数据之前不需要建立连接,发送完数据也不需要释放连接,减少了开销和发送数据之前的握手时延。
- 尽最大努力交付。不保证可靠交付,主机不需要维持复杂的连接状态表,但数据的可靠性不能保证。通过向前纠错、重传已丢失报文等方式,尽可能确保可靠。
- 面向报文。UDP 一次交付一个完整的报文。其对应用层交下来的报文,既不合并,也不拆分,保留这些报文的边界,直接添加首部后就向下交付 IP 层。应用层给 UDP 多长的报文,UDP 一次就发送多长的报文。然而到了 IP 层后,可能根据长度要进行分段,所以过长的 UDP 报文段会影响 IP 层的传输效率。
- 没有拥塞控制。如果网络出现拥塞,也不会使源主机的发送速率降低。如 IP 电话、视频直播等等需要实时的应用,要求源主机以相对稳定的速率发送数据,且允许网络拥塞时丢失部分数据,但强调数据不能有过大时延。
- 支持一对多/多对一通信。???
- 首部开销小。首部只有 8 字节,比 TCP 20字节小得多。
有些应用程序愿意采用不可靠的 UDP,而不愿意采用可靠的TCP。
- TCP出现分组出错、丢失,会选择重传,增加了时延。
- TCP出现拥塞时,拥塞控制另发送方放慢发射速度。
- UDP出现分组出错会直接丢弃,出现拥塞也不会放慢速度。实时性强,适用于语音通话。
UDP 数据报的检验:
- 通过校验和检查:伪首部(IP等关键信息)+ 首部 + 数据。
- 既检查了 UDP 相关信息:源端口号、目的端口号,也检查了 IP 相关信息:源 IP 地址、目的 IP 地址。
IP 数据报的检验:
- 检查:只检查首部。
问题:TCP 主要特点
传输控制协议 TCP(Transmission Control Protocol),TCP 报文段。
面向连接。应用在使用 TCP 通信之前,必须建立 TCP 连接。传输数据完毕后,必须释放 TCP 连接。
可靠交付。通过 TCP 连接传输的数据,无差错、不丢失、不重复、按序到达。
面向字节流。流 stream 是指 TCP 的通信形式是面向字节流。虽然应用程序交付给 TCP的是一个数据块(大小不等),但 TCP 根据 网络拥塞程度 + 对面接受窗口 切分为长度不一的字节流(TCP报文段),添加首部后传输。
- 拥塞控制:根据网络拥塞程度,调整传输的字节长度。
- 流量控制:根据对方接受的窗口大小,调整传输的字节长度。确保发送方的发送速率不要太快,让接收方来得及接受。
点对点 + 全双工通信。
- 点对点:TCP 的通信双方只能是一对一的端口,不能一对多 / 多对一通信;
- 全双工:建立 TCP 连接后,通信双方可以在任何时候发送数据。TCP 连接的两端也有发送 / 接受缓存,临时存放双向通信的数据。
选择重传 + 滑动窗口,实现了 TCP 的可靠传输、流量控制。
问题:TCP 流量控制
TCP 的流量控制:就是抑制发送方的发送速率,既要让接收方来得及接受,也不要使网络拥塞。
- 零窗口等待。TCP 为每一个连接设置 持续计时器,只要 TCP 连接的一方接收到对方的 零窗口通知,就启动 持续计时器,并停止发送。持续计时器到期后,发送一个 零窗口探测报文段(1B) 如果对方回复窗口仍然是零,重新启动持续计时器;若窗口不是零,死锁的僵局打破。
- 滑动窗口。发送方的发送窗口不能超过接收方给的接受窗口的数值。
- 传输效率提升:
- 最大长度。TCP 维护一个最大报文长度 MSS,只要缓存中存放的数据达到 MSS,就组成一个 TCP 报文段发送;
- push 发送。TCP 支持 push 操作,接收方可指定优先度高的报文,优先 push 发送;
- 到期发送。TCP 对缓存的数据添加计时器,如果到期后,即使数据量没达到 MSS,也立即发送。
问题:TCP 拥塞控制
出现资源拥塞的条件是:对资源需求的总和 ≥ 可用资源。
与流量控制不同,拥塞控制是一个全局性的过程,涉及网络内的所有主机、路由器等在网设备,而流量控制仅针对点对点通信。如果不进行拥塞控制,随着负载的提升,全网络设备会进入死锁状态。
- 接收端窗口 rwnd、拥塞窗口 cwnd、往返时间 RTT。
- 发送窗口的上限 =
Min [rwnd, cwnd]
, [接收窗口, 拥塞窗口]。
- 慢开始:
- 在刚开始发送报文段时,可先将拥塞窗口 cwnd = 1,即一个最大报文段 MSS。
- 每收到 1 个报文段的确认,cwnd加 1,即加一个 MSS 大小;
- 相当于:每经过一个传输轮次 RTT,cwnd 翻倍。如果收到 4 个确认,就 + 4。
- 窗口缓慢增加,试探网络的吞吐量。
- 拥塞避免:
- 设置一个慢开始门限 ssthresh;
- 当 cwnd < ssthresh 时,使用慢开始算法;
- 当 cwnd > ssthresh 时,停止慢开始,使用 拥塞避免算法;
- cwnd 每经过一个传输轮次 RTT,cwnd 加一个 MSS 大小,即 “加法增大”。
- 线性规律缓慢增长,速率放缓。
- 乘法减小:
- 慢开始阶段、拥塞避免阶段。出现超时,网络拥塞(没有按时收到确认);
- ssthresh减半,执行慢开始算法。
- 当网络频繁拥塞时,ssthresh 值下降得快,大大减少注入到网络中的分组数。
- 加法增大:
- 拥塞避免算法后,使拥塞窗口 cwnd 缓慢变大,每个 RTT 加1。
- 防止网络过早出现拥塞。
- 拥塞避免算法后,使拥塞窗口 cwnd 缓慢变大,每个 RTT 加1。
数据帧的丢失是网络发生拥塞的征兆,而不是原因:
- 快重传:接收方只要收到失序的报文段,立刻发出重复确认。
- 使发送方及早知道有报文段没有到达对方。
- 接收方立即发送,不进行捎带确认,不选择等待自已发送数据时发送。
- 快恢复:
- 发送方连续收到三个重复的确认。
- 执行 “乘法减小”,让慢开始门限 ssthresh 减半。
- 使 cwnd = ssthresh (已经减半),执行拥塞避免(加法增大),而不是重新慢开始。
问题:TCP 可靠传输
可靠传输的基石,就是 停止等待 + 自动重传 + 滑动窗口。
停止等待:就是发送方没发送完一个分组,就停止发送,等待对方确认。收到确认后再发送下一个分组。停止等待协议要求通信数据包必须有双方协商好的编号。
滑动窗口:停止等待协议每次只允许发送一帧,然后就等待对方确认信息。滑动窗口允许发送方维护一个控制流量的发送窗口,允许一次发送多帧。同时,接收方也维护了一个接受窗口。
- 发送窗口:每收到一个确认帧,就对窗口中已经发送的帧做标记,当靠前的帧已完成确认,窗口就向前滑动,可以发送其他数据帧。
- 接受窗口:每收到一个确认帧,就根据编号按需放在接受窗口的缓存中,同时发送确认帧,当靠前的帧已按序接受,则可以打包向上交付,同时移动接受窗口,接受后面序号的帧。若收到的数据帧在接受窗口之外,直接丢弃。
自动重传请求 ARQ Automatic Repeat ReQuest:就是 确认请求 + 超时重传。发送方的重传是通过超时而自动进行的,不需要接收方请求发送方重传某个出错的分组。
连续 ARQ 协议:发送方不需要收到当前帧确认后,才发送接下来的帧,而是批量发送多个帧,接收方也可以批量接受,然后批量发送确认帧,提升信道使用率。
停止-等待协议:发送窗口大小 = 1,接受窗口大小 = 1;
- 最简单版本,发送一个,确认一个,再发下一个。
后端 N 帧(GBN)协议:发送窗口大小 > 1,接受窗口大小 = 1;
- 累计确认:如果收到了 3 号帧确认,则 1、2、3 都可以确认。
- 捎带确认:接收方可以在发送数据的同时,捎带发送确认信息。
- 按序确认:如果接收方收到的帧不是按序的,只能丢弃该帧和其余后续的帧,重复发送已经接受的确认帧。
选择重传(SR)协议:发送窗口大小 > 1,接受窗口大小 > 1。
- 选择重传:改进了后推 N 帧的丢弃问题,可以选择性的重传出错的帧。接受方也通过一个接受窗口,可以不按序接受帧,然后按序整理好后向上交付。
停止等待协议
- TCP 做为全双工通信方式,有停止等待协议。
假设 A 为发送方,B 为接收方,停止等待协议有 4 种情况:
- 无差错
A 发送完一个分组 M1,就等待 B 确认。B 收到确认后,A 发送下一个分组 M2。
- 数据差错
计时器超市:假如 B 收到 M1 后,检测出了差错,就直接丢弃 M1,不进行收到确认。
超时重传。此时 A 再等待超时计时器(两个发送时延)超时后,收不到确认信息,会超时重传 M1。
- 确认丢失
ACK 丢失:A 发送完 M1 分组后,B 收到 M1 并发送 ACK 确认。但确认帧丢失。此时 A 等待超时计时器后,会执行 超时重传。B 收到同样的 M1 分组后,丢弃重复的 M1分组,继续发送 M1 确认帧。
- 确认迟到
ACK 迟到:有时 B 发送的 M1 确认信息并不是丢失,只是因路由选择较远的问题,让 A 在超时计时器之后的某个时间段收到。此时 A 有可能已经执行了 超时重传 ,进行接下来 M2、M3 的传输,所以收到迟到的 M1 确认信息后,不做任何回应。
停止等待协议的特点:
优点:简单、确保数据的可靠通信,
缺点:信道利用率低,数据必须确认后才继续发送,等待时间过长。
问题:可靠传输和无差错接受的区别
可靠传输:发送到发送什么,接受端就接受什么。可以避免传输差错:帧丢失、帧重复、帧失序。凡事接受端收到的数据帧,就是无差错的。
无差错接受:通信主体(端口)发送什么信息,接收到就能收到什么信息。那么在传输层的数据检验只能保证传输层数据报尽可能的准确,但无法确保上到端口的数据是完全一样的。
问题:TCP 的三次握手
TCP 的传输连接分为三个阶段:建立连接、数据传输、释放连接。
每一方的状态变迁都是:CLOSED / LISTEN ➡️ SYN-SENT ➡️ SYN-RCVD ➡️ ESTABLISHED
- 关闭且被动监听、发送自身同步码、确认对方同步码、建立连接。
第一次握手:
客户端主动打开,通过 TCP 向服务器发出连接 请求报文段,工作有二:
设置报文段首部的同步位 SYN = 1。不携带数据,消耗一个序号。
随机设置序号 seq = x,表明传送数据时的第一个数据字节的序号是 x。
第二次握手:
- 服务器监听到 TCP 数据报,通过同步位 SYN = 1直到这是一个连接的请求,如果同意,回复 确认报文段,工作有三:
- 设置报文段首部的同步位 SYN = 1。不携带数据,消耗一个序号。
- 设置报文段首部的确认位 ACK = 1,序号为 seq = x + 1。
- 设置自己的序号 seq = y,表明传送数据时的第一个数据字节的序号是 y。
第三次握手:
- 客户端收到确认报文,通过确认位 ACK = 1知晓服务器已经确认,发送 确认报文段 + 携带数据,工作有三:
- 客户端 TCP 通知上层应用进程,连接已经建立。
- 设置报文段首部的确认位 ACK = 1,序号为 seq = y + 1。
- 此时 TCP 已经建立,ACK 报文段可以携带数据(没有 SYN 字段),如果不携带数据、只确认则不消耗序号。
问题:TCP 的四次挥手
一旦数据传输结束,客户端或服务器都可以主动请求释放连接。
第一次挥手:
- A 进程主动通知 TCP 关闭连接,停止发送数据,开始被动监听数据,发送 连接释放报文段。
- 设置报文段首部的结束位 FIN = 1,假如此时序号为 seq = u。
- 不携带数据。
第二次挥手:
- B TCP 收到连接释放信号,通知上层进程,发送确认。此时 A 对 B 的 TCP 连接已经中断了。
- 正常确认收到:ack = u + 1,
- 正常发送序号:seq = v,可正常携带数据。
第三次挥手:
- 若 B 已经没有要发送的数据,其应用进程就通知 TCP 释放,发送 链接释放报文段。
- 设置报文段首部的结束位 FIN = 1,假如此时序号为 seq = v + n。
- 不携带数据。
第四次挥手:
- A 收到链接释放报文段后,必须发送确认收到。
- 确认收到:ack = v + n + 1,
- 发送序号:seq = u + 1。
- A 发送报文后,等待 2 MSL 后才真正释放连接。
问题:为什么要三次握手 / 四次挥手
建立连接的两个任务:
- 确认对方身份,确保对方没有拒绝通信。
- 协商双方的初始序号,确保数据按序、不丢失的到达。
所以,和打电话一样,可以举一个打电话的例子。双方建立通信时,要发送一个 自身身份 + 自身序号的报文,也要接受一个对方确认的报文。而能完成这项工作的最少握手次数,就是 3 次。
不使用两次握手,也是为了防止 已失效的连接请求报文段突然又传送到了服务端,因而产生错误:
- 客户端首先向服务器发送了一个SYN报文,由于网络拥堵,迟迟没有收到响应,于是客户端发送了一个新的SYN报文。
- 但是旧的SYN报文比新的SYN报文要到达了服务器,此时服务器就返回SYN+ACK的报文给客户端。
- 因为只有 2 次握手,此时服务器以为连接已经建立,开始传输数据,但其实此时双方的初始序号没有协商成功,客户端并不知道初始序号是什么。
释放连接的两个任务:
- 双方发送释放连接请求,并确认对方收到释放请求。
- 先释放请求的一方,要保持监听,接收对方剩余的数据。
如果双方 “恰好” 同时结束通信,那么有可能 3 次挥手就释放连接:
- A 主动释放连接,发送 FIN = 1,并不再发送数据;
- B 收到释放请求,此时也 “恰好” 好释放连接,发送 确认 + FIN = 1,B 结束 TCP 连接。
- A 收到释放请求,发送释放确认,并在 2MSL 后结束 TCP 连接。
这就解释了为什么大多数情况下要 4 次挥手。因为被动结束的一方,有可能在结束前还要发送数据,所以发送和接收端都要发送 FIN + ACK FIN 这两个报文,一共就是四次。
问题:为什么挥手最后要等待 2MSL?
MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
A 为了保证最后一个 ACK 报文段对方 B 能顺利接收。假设此时这个 ACK 报文段在网络中丢失。B 在 2MSL 中会再次发送一个 FIN 释放请求连接,继续等待 A 的 ACK 报文段,此时 A 依然在自身的 2MSL 中监听,当它又收到一个 FIN 请求后,知晓上一个 ACK 可能已经丢失,立即重发,并继续等待 2MSL。这样就确保双方都能确认释放,进入 CLOSED 状态。
- 特例:如果第一个 ACK 报文丢失,且后面重发的 FIN 报文段也丢失,A 误认为连接结束,主动 CLOSED。而 B 还孜孜不倦的发送 FIN 报文段。在多次没有回应后,也会 CLOSED。
问题:如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP 设有一个保活计时器。客户端如果出现故障,服务器不能一直等待,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为两小时。若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔 75 秒钟发送一次。若一连发送 10 个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
问题:TCP 的重传机制
首先,在正常情况下,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知,叫做确认应答(ACK)。TCP通过序列号 seq 和 ACK 实现可靠传输。如果数据包丢失,会用重传机制解决。
超时重传
自动重传请求 ARQ:(上文)
在发送数据时设定定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据。TCP 会在数据包丢失或者确认应答丢失的情况下发生超时重传。
超时时间的设置:
RTT (Round-Trip Time 往返时延)。数据从网络一端传送到另一端所需的时间 x 2。
RTO 超时重传时间 。是一个基于算法的动态变化值,RTO 略大于报文往返 RTT。
- 当 RTO 较大时,重发慢,效率低;
- 当 RTO 较小时,重发快,可能并没有丢就重发,增加网络拥塞,导致更多的超时。
快速重传
3 次确认快重传。
当某个报文段丢失后,发送端会一直收到某个序号的确认应答,如果发送端连续三次收到了同一个确认应答报文,就会将其所对应的数据进行重发。
为什么是 3 次?因为有可能报文并没有丢失,只是因路由选择的原因时延过长。
第六章 应用层
问题:http 返回码有哪些?
概述
1xx,提示信息,是协议处理中的一种中间状态,还需要后续操作
2XX,表示 Success 成功 的状态码。
3XX,表示 Redirection 重定向 的状态码,客户端需要重新请求。
4XX,表示 Client Error 客户端错误 的状态码,请求报文有误,客户端无法处理。
5XX,表示 Server Error 服务器错误 的状态码。
200系列有三个,服务器:发全部资源(200),不发资源(204),发范围资源(206)
300系列有五个,服务器的资源:永久重定向(301),临时重定向(302、307),post
切换为get
后重定向(303),访问不符合条件(304)
400系列有五个,服务器:无法理解(400),权限验证(401),不允许访问(403),没有该资源(404),禁止该方式访问(405)
500系列有三个,服务器:内部故障(500),上游故障(502),正忙(503)
详述
200 OK:服务器端请求已 正常处理。
204 No Content:一般在 只从客户端发送信息, 服务器不需要发送新信息内容 的情况下使用。和 200 类似,只是客户端无需发送 body 数据。
206 Partial Content:客户端进行 范围请求,服务端返回 小范围内的资源。应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分。
301 Moved Permanently:资源 永久重定向,请求的资源已经不存在了,需改用新的 URL 再次访问。
302 Found:资源 临时重定向,请求资源暂时不在,客户端暂时访问新地址。
- 301 和 302 都会在响应头里添加字段 Location ,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
303 See Other:服务器让客户端把 post 请求切换为 get 请求重定向访问新的地址。
304 Not Modified:缓存重定向,资源已找到,但未符合条件。不具有跳转含义,表示资源未修改,重定向已存在的缓冲文件,用于缓存控制。
307 Temporary Redirect:资源 临时重定向,客户端暂时访问新地址。和 302 类似,有 get 和 post 的访问差别。
400 Bad Request:笼统的错误,服务端 无法理解请求报文,可能是格式错误。
401 Unauthorized:客户端需要对访问进行 权限认证。
403 Forbidden:资源不允许访问。服务器禁止访问资源,并不是客户端的请求出错。
404 Not Found:没有找到资源。
405 Method Not Allowed:服务器 禁止使用该访问方式。
500 Internal Server Error:笼统的错误,服务完成执行请求时 内部发生了故障。
502 Bad Gateway:如果访问的是 “中间商” 服务器(代理服务器、网关服务器),表示中间商服务器正常,但它 无法访问上游服务器。
503 Service Unavailable:服务器无法处理请求,正忙(超负荷、停机维护)。
问题:http 常见字段
- Host 字段:客户端 发送请求时,用来指定服务器的域名。
- Content-Length 字段:服务器 在返回数据时表明本次回应的数据长度。
- Connection 字段 :客户端 要求服务器使用 TCP 持久连接,以便其他数据发送复用。HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的 HTTP,需要指定 Connection 首部字段的值为 Keep-Alive 。
- Content-Type 字段 :服务器 告知客户端本次数据是什么格式;客户端 请求时声明自己可以接受哪些数据格式。
- Content-Encoding 字段:服务器 返回的数据使用的压缩格式。 客户端 在请求时声明可以接受的压缩格式。
问题:HTTP 常用的请求方式 (9)
HTTP1.0: GET
、POST
、HEAD
HTTP1.1: PUT
、PATCH
、DELETE
、OPTIONS
、TRACE
、CONNECT
- GET:通用获取数据
- POST:提交数据
- DELETE:删除数据
- TRACE:追踪请求-响应的传输路径,用于测试或诊断
- HEAD:获得报文首部
- PUT:修改数据
- PATCH:对PUT的补充,对已知资源部分更新
- CONNECT:建立连接隧道,用于代理服务器
- OPTIONS:列出可对资源实行的请求方法,常用于跨域
问题:GET 和 POST 的区别
相同:
- 两者都是应用层中 HTTP协议中的两种发送请求的方式,都通过 TCP 连接的可靠传输。
- 因 GET 和 POST 并不是强制约定的规则,而是一种倡导式的语义规范,只要前后端协商好,GET 也能当 POST 使用,body 上携带数据发送,只是这种方式是不建议的。
不同:
- 含义不同。
- GET 是请求从服务器获取资源,这个资源可以是静态的文本、页面、图片视频等。
- POST 是向服务器提交数据,数据通常放在 body 中。
- 安全不同。所谓安全不同,是针对服务器而言的。安全 指请求方法不会破坏服务器上的资源。幂等,意思是多次执行相同的操作,结果都是相同的。
- GET 是安全且幂等的,它是 只读 操作,无论做多少次请求,服务器的数据不变。
- POST 是不安全、不幂等的。不安全:POST 会向服务器新增 / 修改数据,造成服务器资源的改变;不幂等:多次提交相同的数据,服务器也可能会保存多记录。
- 额外数据。POST 可以把数据放在请求体 (request body) 中传输数据。GET 只能通过 URL 传输。这导致:URL 的长度存在限制,数据总量受限;传输参数暴露在 URL 中,用户可以感知到。
- 数据包数量不同。这是浏览器的通常方式:
- GET:浏览器会把 请求行 + 头 + 体 一并发送出去,服务器响应200(返回数据)
- POST:类似 三次握手,浏览器先发送 请求行 + 头,服务器响应100 continue,再发送 请求体,服务器响应 200 ok(返回数据),确保服务器做好接受数据的准备。
问题:HTTP 的特点 / 缺点
HTTP 是超文本传输协议,也就是 HyperText Transfer Protocol。HTTP 是一个传输层基于 TCP 连接,在应用层专门在 两点之间传输 文字、图片、音频、视频等 超文本数据 的 约定和规范。
特点:无连接
、无状态
、灵活
、简单快速
- 无连接:每一次请求都要连接一次,请求结束就会断掉,不会保持连接。
- 无状态:每一次请求都是独立的,请求结束不会记录连接的任何信息 (提起裤子就不认人的意思),减少了网络开销,这 是优点也是缺点。减轻服务器的负担,不用记录所有客户端的信息。
- 可以通过携带 cookie 来控制客户端的状态,比如 sso 登陆。
- 灵活:通过http协议中头部的
Content-Type
标记,可以传输任意数据类型的数据对象(文本、图片、视频等等),非常灵活。 - 简单快速:发送请求访问某个资源时,只需传送请求方法和 URL 就可以了,使用简单,正由于 http 协议简单,使得 http 服务器的程序规模小,因而通信速度很快。
缺点:无状态
、不安全
、明文传输
、队头阻塞
- 无状态:请求不会记录任何连接信息,没有记忆,就无法区分多个请求发起者身份是不是同一个客户端的。如果后续处理需要前面的信息,则必须重传。这样可能导致每次连接传送的数据量增大。
- 不安全:
- 明文传输 可能被窃听:账号信息泄露。
- 缺少身份认证 可能遭遇伪装:访问到假的银行网站。
- 缺少 报文完整性验证 可能遭到篡改:网页注入垃圾广告。
- 队头阻塞:开启 长连接 时,只建立一个 TCP 连接,同一时刻只能处理一个请求,那么当请求耗时过长时,其他请求就只能阻塞状态。
问题:HTTP 报文组成部分
http报文:由请求报文
和响应报文
组成
请求报文:由请求行
、请求头
、空行
、请求体
四部分组成
响应报文:由响应行
、响应头
、空行
、响应体
四部分组成
- 请求行 :包含http方法,请求地址,http协议以及版本
- 请求头/响应头:通过 key / value 告诉服务端我要哪些内容,要注意什么类型等。
- 空行:用来区分首部与实体,因为请求头都是 key / value 格式,当解析遇到空行时,服务端就知道下一个不再是请求头部分,就该当作请求体来解析。
- 请求体:请求的参数
- 响应行:(状态行)包含 http 协议及版本、数字状态码、状态码英文名称
- 响应体:服务端返回的数据
问题:HTTP1.1 持久连接/长连接
HTTP 1.0 协议:采用的是 "请求-应答" 模式。每发起一个请求,都要新建一次 TCP 连接(三次握手),而且是串行请求,做了无谓的 TCP 连接建立和断开,增加了通信开销。http
协议为 无连接 的协议。
HTTP 1.1 协议:支持长连接,即请求头添加 Connection: Keep-Alive
,使用 Keep-Alive模式 (又称持久连接) 建立一个 TCP
连接后使客户端到服务端的连接持续有效,可以发送/接受多个 http
请求/响应。当出现对服务器的后续请求时,Keep-Alive 功能避免了建立或者重新建立连接。
优点
- 减少 CPU 及内存的使用,因为不需要经常建立和关闭连接
- 支持管道化 的请求及响应模式
- 减少网络堵塞,因为减少了TCP请求
- 减少了后续请求的响应时间,因为不需要等待建立TCP、握手、挥手、关闭TCP的过程
- 发生错误时,也 可在不关闭连接的情况下进行错误提示
缺点
- 长连接建立后,如果一直保持连接,服务器资源浪费,影响到 并发数。
- 可能造成 队头堵塞,造成信息延迟
避免缺点
- 客户端即时断开。客户端请求头声明:
Connection: close
,本次通信后就关闭连接; - 服务端超时断开。如 Nginx,设置
keepalive_timeout
长连接超时时间。 - 服务端限制并发。如 Nginx,设置
keepalive_requests
长连接请求次数上限。 - 设置保活计时器。如果 TCP 闲置 60s 后,客户端可主动发送侦测包,确定 TCP 的连接状态。如果没收到 ACK 确认,就10s 后继续发送。连续 5 次失败,则关闭 TCP 连接。
问题:HTTP1.1 管道化/管线化
http1.1在使用长连接的情况下,建立一个连接通道后,连接上消息的传递类似于
- 请求1 -> 响应1 -> 请求2 -> 响应2 -> 请求3 -> 响应3
管道化 连接的消息就变成了类似这样
- 请求1 -> 请求2 -> 请求3 -> 响应1 -> 响应2 -> 响应3
管线化 :类似 TCP 连接的滑动窗口机制。基于长连接下,发一个请求后不必等待确认,就继续发其他请求。
- 优点:可以减少整体的响应时间。
- 缺点:队头阻塞。服务器还是 会按照请求的顺序响应 请求,所以如果有许多请求,而前面的请求响应很慢,就会产生队头阻塞。
问题:HTTPS
HTTPS 是 超文本传输安全协议,即 HTTP + SSL/TLS。说白了,就是一个加强版的 HTTP。
- TLS 是 SSL 的升级版,目前主要用的是
TLS 1.2
和TLS 1.3
,分别是 2008 和 2018。 - OpenSSL 是 开源版本,从 2010 年开始维护。、
TLS 保证了计算机网络安全的五个特性:机密性
、可用性
、完整性
、认证性
、不可否认性
。
HTTP 和 HTTPS 的区别
- 安全性。HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。 HTTPS 在 TCP 和 HTTP 应用层之间加入了 SSL/TLS 安全协议,使报文能够加密传输。
- 额外握手。HTTP 在 TCP 三次握手之后便可进行 HTTP 的报文传输。
HTTPS 在 TCP三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
- TLS 是 传输层协议。
- 握手次数:TLS 1.2 版本 7 次,TLS 1.3 版本 6 次。
- 不同端口。HTTP 的端口号是 80,HTTPS 的端口号是 443。
- 额外证书。如果使用 HTTPS 协议,服务器需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的,而额外的认证证书是需要收费的。
- 额外状态。HTTP是 无状态 的,HTTPS是 有状态 的。
HTTPS 优缺点
优点
- 内容加密,中间无法查看原始内容。
- 身份认证,保证用户访问正确。如访问百度,即使 DNS 被劫持到第三方站点,也会提醒用户没有访问百度服务,可能被劫持。
- 数据完整性,防止内容被第三方冒充或篡改。
虽然不是绝对安全,但是现行架构下最安全的解决文案了,大大增加了中间人的攻击成本。
缺点
- 收费,功能越强大的证书费用越贵。
- 证书需要绑定 IP,不能在同一个 IP 上绑定多个域名。
- https 双方加密 / 解密,耗费更多服务器资源。
- https 握手更耗时,降低一定用户访问速度。
问题:HTTPS 加密算法
HTTPS是通过 3 点实现数据加密安全:
- 非对称加密算法。公钥和私钥,交换对称加密中使用的密钥。
- 数字证书。数字证书验证身份,验证公钥是否是伪造。
- 对称密钥。利用对称密钥加解密后续传输的数据。
https 使用混合加密的形式,对称加密和非对称加密都会用到。
对称加密算法
加密和解密使用同一个密钥。如 AES、DES
。加解密过程:
- 浏览器给服务器发送一个随机数
client-random
和一个支持的加密方法可选列表。 - 服务器给浏览器返回另一个随机数
server-random
和双方都支持的加密方法。 - 两者用加密方法将两个随机数混合生成密钥,这就是通信是加解密的密钥。
问题:双方如何安全的传递两个随机数和加密方法。若直接传递,过程中可能被窃取,别人就能成功解密拿到数据。
不对称加密算法
有一对密钥,有 公钥 (public key)和 私钥 (private key),其中一个密钥加密后的数据,只能让另一个密钥进行解密。如 RSA
、ECDHE
。加解密过程:
- 浏览器给服务器发送一个随机数
client-random
和一个支持的加密方法可选列表; - 服务器把另一个随机数
server-random
、加密方法、公钥 传给浏览器。 - 然后浏览器用公钥将两个随机数加密,生成密钥,这个密钥只能用 私钥 解密。
问题:使用公钥反推出私钥的代价非常高,可能是几百年。但不是做不到,随着计算机运算能力提高,非对称密钥至少要 2048 位才能保证安全性,这就导致性能上要比对称加密要差很多。
TLS实际用的是两种算法的混合加密。
- 通过 非对称加密算法 交换 对称加密算法 的密钥。交换完成后,再使用对称加密进行加解密传输数据。这样就保证了会话的机密性。过程如下:
- 浏览器给服务器发送一个随机数
client-random
和一个支持的加密方法列表。 - 服务器把另一个随机数
server-random
、加密方法、公钥 传给浏览器。 - 浏览器又生成另一个随机数
pre-random
,并用公钥加密后传给服务器。 - 服务器再用私钥解密,得到
pre-random
。 - 浏览器和服务器都将三个随机数用加密方法混合生成最终密钥。
问题:这样即便被截持,中间人没有私钥就拿不到 pre-random
,就无法生成最终密钥。
可又有问题,如果一开始就被 DNS 截持,我们拿到的公钥是中间人的,而不是服务器的,数据还是会被窃取。解决:使用 数字证书。
数字证书 (数字签名)
可以验证服务器身份。防止中间人攻击。既然我们不信任服务器的身份,那么就找一个信任的中间服务器( CA 机构),通过它的认证来信任服务器。
- 中间人劫持:假如请求被中间人截获,中间人把他自己的公钥给了客户端,客户端收到公钥就把信息发给中间人了,中间人解密拿到数据后,再请求实际服务器,拿到服务器公钥,再把信息发给服务器。这样信息就被窃取了。
数字证书需要向有权威的 认证机构(CA) 获取授权给服务器。
申请数字证书、CA机构 生成证书的步骤:
- 服务器和 CA 机构分别有一对密钥 (公钥和私钥)。
- 服务器向 CA 机构递交公钥、公司、站点等信息并等待认证;
- CA 机构通过线上、线下等渠道验证服务器的真实性、合法性等,然后准备生成证书。
- CA 机构通过摘要算法生成 服务器公钥 的 摘要 (哈希摘要)。
- 摘要算法:保证信息完整性,特点是单向性、无法反推原文,如:MD5算法、散列函数、哈希函数。
- CA 机构通过 CA私钥 及特定的签名算法 加密 摘要,生成 签名。
- 把 签名、服务器公钥、组织信息、CA 信息、有效时间、证书序列号等 明文信息,打包放入 数字证书,并返回给服务器。
证书验证步骤:
- 解密:使用 CA公钥 和 签名算法 对 数字签名 进行解密,得到服务器公钥的 摘要。
- 用 摘要算法 对证书里的 服务器公钥 生成摘要。
- 最后把两个摘要进行比对,如果一致说明证书合法,服务器公钥正确,否则就是非法。
这里的核心,是 CA 的公钥必须可信,所以浏览器可能还要对 CA 进行验证,则要找到 CA 的数字签名,从更大的 CA 机构验证这个 CA 机构... 最后内置 CA 对应的证书称为根证书,根证书是最权威的机构,它们自己为自己签名,我们把这称为自签名证书。
问题:HTTPS 原理
安全层有两个主要的职责:对发起 HTTP 请求的数据进行加密操作和对接收到 HTTP 的内容进行解密操作。
HTTPS 融合了 对称加密 + 非对称加密 + 数字证书。达到性能与安全最大化。这套整合的技术我们称之为SSL(Secure Scoket Layer 安全套接层)。所以 https 并非是一项新的协议,它只是在http上披了一层加密的外壳。
HTTPS 的执行流程
或者:
问题:队头阻塞
队头阻塞 Head-of-line blocking,HOL blocking。
- 存在于HTTP层、TCP层,在HTTP1.x 时两个层次都存在该问题。
TCP 层
TCP 协议在收到数据包之后,这部分数据可能是乱序到达的,数据必须按序整合后向上交付。如果其中某个包丢失了,就必须等待重传,从而出现某个丢包数据阻塞整个连接的数据使用。
- TCP 层,可以通过优先级调整、滑动窗口增大等方式来解决。
HTTP/1.1
管道化的连接方式,会导致 队头阻塞(对头堵塞)的产生。
http1.0
协议采用的是 请求-应答
模式,报文必须是 一发一确认
,就形成了一个 先进先出
的串行队列,没有轻重缓急的优先级,只有入队的先后顺序,排在最前面的请求最先处理。这导致如果队首的请求耗时过长,后面的请求就只能处于阻塞状态。
解决方式:
- 并发连接。对同一个域名的访问,分配多个长连接,相当于增加了任务队列。浏览器标准中一个域名并发连接可以有 6 个。(Chrome 6 个 / Firefox 8 个)。
- 域名分片。同一个域名最多 6 个并发,那多准备 二级域名。比如a.baidu.com,b.baidu.com,当访问 baidu.com 时,让不同的资源从不同的分域名获取,而它们都指向同一台服务器,并发更多的长连接了。
HTTP 2
多路复用机制,解决 HTTP 层的队头阻塞。参考问题:HTTP/2 演变。
HTTP3
直接不跟 TCP 玩了,使用 UDP。参考问题:HTTP/3 演变。
问题:HTTP/1.1、HTTP/2、HTTP/3 演变
HTTP/1.1
1 持久连接 + 管线化
HTTP/1.1 中增加了持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持。
使用 CDN 的实现域名分片机制。将一个页面的资源利用多个域名下载,提高 tcp 并发数量。
- 持久连接在 HTTP/1.1 中是默认开启的,不需要专门去 HTTP 请求头设置信息。
- Connection: close 不采用持久连接;Keep-Alive 默认开启。
- 持久连接:keep-alive 同域名的链接限制是 6 个
- 管线化:可以批量发送 / 批量确认
- FireFox、Chrome 都做过管线化的试验,但是由于 队头阻塞 等问题,最终放弃。
2 支持虚拟主机
HTTP/1.1 实现一台物理主机上,绑定多个虚拟主机,每个虚拟主机都有自己单独的域名,这些域名又公用一个 IP 地址。
请求头增加 Host 字段。表示当前的域名地址,这样服务器就可以根据不同的 Host 值做不同的处理。
3 支持动态生成
HTTP/1.0 时,需要在响应头中设置完整的数据大小,如 Content-Length: 901。
基于模板引擎技术的 HTML 网页大小变得不确定。浏览器不知道最终返回的数据量大小, 导致了浏览器无法数据是否传输完成。
HTTP/1.1 推出 chunk transfer机制,从后端解决了这个问题。 服务端将数据分割成多个大小不一的数据块,并附上大小信息。最后使用一个没有 0 长度的块,专门作为发送三数据完成的标志。
4 客户端 Cookie
HTTP/1.1 还引入了客户端 Cookie 机制,可以保持登录状态。
客户端输入用户名 + 密码,服务器验证通过后,会注入 Cookie 字段:Set-Cookie: UID=3431uad;
写到相应头中。
客户端再次访问服务器,会把 Cookie 字段写到请求头,服务器验证 Cookie 有效(正确 + 未过期)可让客户端保持登录状态。
HTTP/2
HTTP/2 在 2018 年就开始得到了大规模的应用,HTTP/1 的一大堆缺陷都得到了解决。
HTTP/1.1 对带宽的利用率不高,主要集中在 3 个问题:
1. TCP 的慢启动
TCP 建立连接后,为了拥塞控制,按照规定需要采用 慢启动/慢开始 策略。在刚开始发送报文段时,将拥塞窗口 cwnd = 1,即一个最大报文段 MSS。然后每个传输轮次 RTT 翻倍。
但是,最开始建立 TCP 可能要下载一些需要首屏渲染的关键文件,但耗费的时间却比正常的多。
2. 多条 TCP 连接竞争带宽
如果客户端对同一个服务器请求,同时开启了多条 TCP 连接,那么这些连接会竞争固定的带宽。每条 TCP 连接之间也并不知道对方在传输什么文件,哪些重要,哪些不重要。所以任务没有个轻重缓急。
3. 队头阻塞
HTTP/1.1 使用持久连接时,多个请求任务公用一个 TCP 管道,存在队头阻塞的问题。当头的请求没有确认时,队列中其他的任务要白白等待。有些关键的任务因为要按序而没有提前发送。
HTTP/2 引入 多路复用。把 HTTP 拆分为帧的形式,形成数据流。
本质是将串行的请求处理并行化,为了实现功能需要双方多维护一个数据结构 — 帧。
解决问题 1 和 2:HTTP/2 使用 一个域名只使用一个 TCP 长连接来传输数据。这样整个页面资源的下载过程只需要一次慢启动,同时也避免了多个 TCP 连接竞争带宽所带来的问题。
解决问题 3:HTTP/2 实现资源的 并行请求(不按序)。任何时候都可以将请求发送给服务器,不需要按序,等其他请求完成。服务器也可以随时返回处理好的请求资源给浏览器,可以根据优先级有选择的不按序响应。
多路复用 的延伸特性:
- 数据优先级。浏览器在发送请求时,可标记请求的优先级,期待服务器优先返回。服务器也可以根据自身需求,选择哪些请求优先返回。
- 服务器推送。服务器可直接将数据提前推送到浏览器。当用户请求一个 HTML 页面之后,服务器知道该页面会引用了重要的 JavaScript 和 CSS 文件,所以会附带将文件一并发送给浏览器。这样当浏览器解析完 HTML 文件之后,就能直接开始解析 CSS、执行 Js。加速了首次打开页面的速度。
- 头部压缩。HTTP/2 对请求头和响应头进行了压缩。
多路复用的实现方式:
HTTP/2 在应用层进一步划分为:构建请求 和 二进制分帧 两个步骤。
为了提升兼容性,开发者无需对 请求行、头、体进行修改。HTTP/2直接增加了一个 二进制分帧 的过程:
- 浏览器构建好的请求或响应报文。
- 一个报文通过二进制分帧层处理,被转换为 n 个带 有请求 ID 编号的帧
- 可选:向下交付 TLS 安全加密。
- 向下交付 TCP 传输帧。
服务器接收到帧后:
- 通过帧上的 ID 编号,还原为 HTTP 请求,然后准备响应报文。
- 服务器会根据自己的喜好来决定优先返回哪些内容。比如服务器可能早就缓存好了 index.html 和 bar.js 的响应头信息,那么就会优先把这两个数据返回。
- 返回的流程是一样的,HTTP 响应拆分为 n 个帧,然后 TCP 封装后发送。
HTTP/3
不论是 HTTP/1.1 还是 HTTP/2,都是基于 TCP 的 HTTP 协议。这就不可避免的带上了 TCP 的缺点:
- 队头阻塞。TCP 数据帧必须是按需到达,按序整理和向上交付的。滑动窗口、TCP 并发并不能从根本上解决问题。
- 建立连接。在正式通信前,可能要 3-4 个 RTT 传输轮次 (Round-Trip Time 往返时延)
- TCP 基于可靠传输,采用了三次握手的建立连接方式。需要 1.5 个 RTT。
- 为了确保通信安全,HTTPS 增加 TLS / SSL 的握手时间。需要约 2 个 RTT。
- 慢启动。TCP 为了拥塞控制,要从 1 慢开始。
由于 TCP 无法改变:
- 中间设备的固化,多数中间设备是不进行固件更新的:路由器、防火墙、交换机。
- TCP 协议的加载和解析方式是基于操作系统内核的。
引入新的 QUIC 协议。基于 UDP,集成 TCP + HTTP/2 的多路复用 + TLS 的一套协议。
- 实现 TCP 的 流量控制、可靠传 功能。QUIC 提供数据包重传、拥塞控制等 TCP 特性,解决 UDP 不可靠的传输。
- 集成了 TLS 加密功能。目前 QUIC 集成 TLS1.3,比早期版本减少握手花费的 RTT 个数。
- 实现 HTTP/2 的 多路复用功能。和 TCP 不同,QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。
- 快速握手。QUIC 是基于 UDP,实现使用 0-RTT 或者 1-RTT 来建立连接。用最快的速度来发送和接收数据,大大提升首次打开页面的速度。
问题:常见网络攻击方式
被动攻击:是指攻击者从网络上窃听他人的通信内容,通常把这类攻击称为截获。由于攻击者没有修改数据,使得这种攻击很难被检测到。
- 两种形式:消息内容泄露攻击 和 流量分析攻击。
主动攻击:直接对现有的数据和服务造成影响,常见类型有:
- 篡改:攻击者故意篡改网络上送的报文,甚至把完全伪造的报文传送给接收方。
- 恶意程序:恶意程序种类繁多,包括计算机病毒、计算机蠕虫、特洛伊木马、后门入侵、流氓软件等等。
- 拒绝服务Dos:攻击者向服务器不停地发送分组,使服务器无法提供正常服务。
DNS 劫持:域名劫持
- 将原域名对应的IP地址进行替换,使用户访问到错误网站。
CSRF 攻击:跨站请求伪造 Cross-site request forgery。
- 一种挟持用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。
DOS:拒绝服务 Denial of Service
- 引起拒绝行为的攻击。最常见的 DoS 攻击就有 计算机网络宽带攻击、连通性攻击。
DDoS:分布式拒绝服务 Distributed Denial of Service
- 处于不同位置的多个攻击者同时向目标发动攻击。
XSS:跨站脚本攻击(Cross-Site Scripting)
- 攻击者在 Web 页面中插入恶意 html 代码。当用户浏览网页的时候,嵌入其中 Web 里面的 html 代码会被执行,从而达到恶意攻击用户的特殊目的。
问题:DNS 域名系统
功能:Internet 的命名系统。将用户认知的域名,解析为主机能识别的 IP 地址。
四种服务器:
本地域名服务器:本地个人/公司/大学。
- 主机发送DNS查询请求时,先发送给本地域名服务器。
根域名服务器:知道所有顶级域名服务器。
- 本地域名服务器无法解析,首先求助于根域名服务器。
顶级域名服务器:负责该服务器下所有的二级域名服务器。
权限域名服务器:一个区。
域名转换过程:递归 + 迭代(常用)、递归 + 递归。
- 某进程需要查询域名的 IP 时,基于 UDP 用户数据报发送查询信息。
- 先查看 主机 是否有缓存,再向本地域名服务器查询。
- 本地域名服务器 先查询本服务器是否有缓存,找不到则返回下一个查询地址(根)
- 根域名服务器 先查询是否有缓存,找不到则返回下一个查询地址(顶级)
- 顶级域名服务器 先查询是否有缓存,找不到则返回下一个查询地址(顶级 / 权限)
- 顶级域名服务器 先查询是否有缓存,找不到则返回下一个查询地址(权限)
关于缓存:
- 本地服务器,初次是没有缓存列表的。经过一次查询后,得到 IP 地址,会加入缓存中。
- 缓存的地址有生命周期,到期后自动删除。防止长期不访问 / 地址失效。
- 缓存的地址如果不可达,则证明虽然未到生命周期,但地址失效,则删除地址。
问题:什么是 WebSocket
Websocket是一个持久化的网络通信协议,可以在单个 TCP 连接上进行 全双工通讯,没有了 Request
和 Response
的概念,两者地位完全平等,连接一旦建立,客户端和服务端之间实时可以进行双向数据传输。
- websocket 虽然是独立于 HTTP 的一种协议,但是 websocket 必须依赖 HTTP 协议进行三次握手,握手成功后,数据就直接从 TCP通道传输,与 HTTP 无关了。
- socket 是套接字,不是一个协议,是一个 IP地址 + 端口的通用封装接口,传输层使用
使用场景:弹幕、消息订阅、多玩家游戏、协同编辑、股票基金实时报价、视频会议、在线教育、聊天室等应用实时监听服务端变化。
kafka 和 websocket 的配合使用:
前端每打开一个客户端就会和后台建立一个websocket的长连接,每个连接中都会建立kafka的消息监听。当kafka监听到消息时,会通过每个websocket连接发送的相应的客户端,从而实现数据流的实时显示。
开发依赖包:kafka-node-master 和socket.io
问题:什么是 Kafka
Kafka 是由 Linkedin
公司开发的,它是一个分布式的,支持多分区、多副本,基于 Zookeeper 的分布式消息流平台,它同时也是一款开源的 基于发布订阅模式的消息引擎系统。
消息队列有:点对点、发布-订阅两种模式。
https://juejin.cn/post/6844903495670169607