网络分层模型
网络分层是一种将复杂的网络通信系统按功能划分为多个层次的设计方法,每个层次专注于特定的任务,层与层之间通过接口进行交互。这种设计使得网络系统的开发、维护和扩展更加便捷。下面为你介绍两种常见的网络分层模型。
OSI 参考模型
开放式系统互联通信参考模型(Open System Interconnection Reference Model),由国际标准化组织(ISO)制定,共分为 7 层,从下到上依次为:
- 物理层(Physical Layer)
- 功能:负责在物理介质上传输原始的比特流,定义了物理设备的电气、机械、功能和规程特性,如电缆类型、接口形状、信号电压等。
- 设备:常见的物理层设备有网卡、网线、集线器、中继器等。
- 数据链路层(Data Link Layer)
- 功能:将物理层接收到的比特流组织成数据帧,进行差错检测和纠正,同时负责介质访问控制,确保多个设备在共享介质上有序通信。
- 协议:以太网协议、PPP 协议等。
- 设备:交换机、网桥属于数据链路层设备。
- 网络层(Network Layer)
- 功能:主要负责数据包的路由选择和转发,将数据从源节点传输到目的节点,同时处理网络拥塞和网络互联等问题。
- 协议:IP 协议、ICMP 协议、ARP 协议等。
- 设备:路由器是典型的网络层设备。
- 传输层(Transport Layer)
- 功能:为应用进程之间提供端到端的可靠通信或高效通信服务。可靠传输如 TCP 协议,会进行流量控制、拥塞控制和差错恢复;高效传输如 UDP 协议,速度快但不保证可靠性。
- 协议:TCP 协议、UDP 协议。
- 会话层(Session Layer)
- 功能:负责建立、管理和终止应用程序之间的会话,包括会话的同步、会话的恢复和会话的结束等。
- 协议:NetBIOS、RPC 等。
- 表示层(Presentation Layer)
- 功能:处理数据的表示和转换,如数据的加密、解密、压缩、解压缩等,确保不同系统之间能够正确理解和处理数据。
- 协议:JPEG、ASCII、SSL/TLS 等。
- 应用层(Application Layer)
- 功能:为用户的应用程序提供网络服务,如文件传输、电子邮件、远程登录等。
- 协议:HTTP、FTP、SMTP、DNS 等。
TCP/IP 模型
传输控制协议/网际协议(Transmission Control Protocol/Internet Protocol),是互联网实际使用的网络模型,共分为 4 层:
- 网络接口层(Network Interface Layer)
- 功能:负责将 IP 数据包封装成适合在物理网络上传输的帧,并通过物理网络发送和接收数据。该层对应 OSI 模型的物理层和数据链路层。
- 网际层(Internet Layer)
- 功能:主要功能与 OSI 模型的网络层相似,负责数据包的路由和转发,使用 IP 协议进行编址和寻址。
- 协议:IP 协议、ICMP 协议、ARP 协议等。
- 传输层(Transport Layer)
- 功能:与 OSI 模型的传输层功能相同,提供端到端的可靠或不可靠传输服务。
- 协议:TCP 协议、UDP 协议。
- 应用层(Application Layer)
- 功能:包含了 OSI 模型中会话层、表示层和应用层的功能,为用户应用程序提供网络服务。
- 协议:HTTP、FTP、SMTP、DNS 等。
两种模型对比
- OSI 模型:理论上较为完善,层次划分细致,各层功能明确,但实现复杂,实际应用较少。
- TCP/IP 模型:简洁实用,是互联网的事实标准,与实际网络应用紧密结合,但层次划分不够严谨。
传输层协议TCP/UDP
TCP和UDP的区别
TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protocol,用户数据报协议)是传输层两种重要的协议,它们在多个方面存在显著区别,以下详细介绍:
连接特性
- TCP:面向连接的协议。在数据传输前,需要通过三次握手建立连接,传输完成后,再通过四次挥手断开连接。这种连接机制确保了通信双方的可靠性和数据传输的有序性。例如,在文件下载场景中,TCP 能保证文件完整无误地传输到客户端。
- UDP:无连接的协议。发送数据前不需要建立连接,也无需在传输结束后断开连接。发送方只需将数据封装成数据包发送出去,接收方接收数据包即可。像在线视频直播,使用 UDP 能快速将视频数据发送给用户,即使有少量数据包丢失,对整体观看影响也不大。
可靠性
- TCP:提供可靠的数据传输。它通过序列号、确认应答(ACK)、重传机制、流量控制和拥塞控制等手段,确保数据无差错、不丢失、不重复且按序到达。如果发送方发送的数据没有收到接收方的确认应答,就会重新发送该数据。比如在金融交易系统中,使用 TCP 能保证每一笔交易信息准确无误地传输。
- UDP:不可靠的传输协议。它不保证数据的可靠传输,不提供重传、确认应答等机制,数据包可能会丢失、重复或乱序。但这种特性也使得 UDP 的传输效率较高,适合对实时性要求高、对少量数据丢失不敏感的应用。
传输效率
- TCP:由于要保证可靠性,需要进行连接建立、确认应答、重传等操作,这些额外的开销会降低传输效率,增加传输延迟。例如,在进行大量数据传输时,TCP 的握手和确认过程会消耗较多时间。
- UDP:没有连接建立和维护的开销,也无需等待确认应答,传输速度快,延迟低。像实时语音通话、在线游戏等场景,使用 UDP 能及时传输数据,保证实时性。
数据传输形式
- TCP:面向字节流的传输。发送方将应用层的数据看作无结构的字节流,TCP 会将字节流分成适当大小的数据块进行传输,接收方再将接收到的数据块重新组装成完整的字节流。这种方式使得数据的边界不明显,需要应用层自己处理数据的分割和合并。
- UDP:面向报文的传输。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界,在添加 UDP 首部后直接发送。接收方收到的 UDP 报文可以直接交给应用层处理。
首部开销
- TCP:首部开销较大,固定部分有 20 个字节,还可能包含可选字段,最多可达 60 个字节。这些额外的信息用于实现连接管理、可靠性控制等功能。
- UDP:首部开销较小,固定为 8 个字节,只包含源端口、目的端口、长度和校验和等基本信息。
应用场景
- TCP:适用于对数据准确性要求高、对实时性要求相对较低的应用,如文件传输(FTP)、电子邮件(SMTP)、网页浏览(HTTP)等。
- UDP:适合对实时性要求高、对数据准确性要求相对较低的应用,如实时音视频传输(如 WebRTC、RTSP)、在线游戏、DNS 查询等。
TCP怎么保障传输可靠性
TCP(传输控制协议)通过一系列机制来保障数据传输的可靠性,下面从连接管理、数据确认、重传机制、流量控制和拥塞控制等方面详细介绍。
连接管理
三次握手建立连接
在数据传输前,TCP 通过三次握手建立可靠的连接,确保双方都具备发送和接收数据的能力。
- 第一次握手:客户端向服务器发送一个带有 SYN(同步)标志的数据包,其中包含客户端随机生成的序列号
seq = x,表示客户端希望建立连接。 - 第二次握手:服务器收到客户端的 SYN 包后,会发送一个 SYN + ACK 数据包。其中 SYN 标志表示服务器同意建立连接,包含服务器随机生成的序列号
seq = y;ACK 标志用于确认客户端的请求,确认号ack = x + 1。 - 第三次握手:客户端收到服务器的 SYN + ACK 包后,发送一个 ACK 数据包,确认号
ack = y + 1,表示客户端已经收到服务器的连接确认。此时连接建立成功。
四次挥手断开连接
数据传输完成后,通过四次挥手断开连接,确保双方都能正确释放资源。
- 第一次挥手:客户端向服务器发送一个带有 FIN(结束)标志的数据包,表示客户端没有数据要发送了,但仍可以接收数据。
- 第二次挥手:服务器收到客户端的 FIN 包后,发送一个 ACK 数据包,表示已经收到客户端的关闭请求,服务器还可能有数据要发送。
- 第三次挥手:服务器发送完剩余数据后,向客户端发送一个 FIN 数据包,表示服务器也没有数据要发送了。
- 第四次挥手:客户端收到服务器的 FIN 包后,发送一个 ACK 数据包,确认收到服务器的关闭请求,随后双方关闭连接。
数据确认
TCP 使用序列号和确认应答(ACK)机制来确保数据的可靠传输。
- 序列号:每个 TCP 数据包都包含一个序列号,用于标识该数据包在整个字节流中的位置。接收方可以根据序列号按序接收和组装数据。
- 确认应答:接收方收到数据包后,会发送一个确认应答(ACK)数据包,确认号为下一个期望接收的数据包的序列号。发送方收到确认应答后,就知道该数据包已经成功到达接收方。
重传机制
如果发送方在一定时间内没有收到某个数据包的确认应答,就会认为该数据包丢失,会重新发送该数据包。常见的重传触发条件有两种:
- 超时重传:发送方为每个发送的数据包设置一个超时定时器,如果在定时器超时之前没有收到确认应答,就会重传该数据包。超时时间通常会根据网络状况动态调整。
- 快速重传:当发送方连续收到 3 个相同的确认应答时,表明有数据包丢失,但网络尚未完全拥塞。此时,发送方不等超时重传定时器到期,就立即重传丢失的数据包。
在数据包丢失或延迟的情况下,重新发送数据包,直到收到对方的确认应答(ACK)。TCP 重传机制主要有:基于计时器的重传(也就是超时重传)、快速重传(基于接收端的反馈信息来引发重传)、SACK(在快速重传的基础上,返回最近收到的报文段的序列号范围,这样客户端就知道,哪些数据包已经到达服务器了)、D-SACK(重复 SACK,在 SACK 的基础上,额外携带信息,告知发送方有哪些数据包自己重复接收了)。关于重传机制的详细介绍,可以查看详解 TCP 超时与重传机制这篇文章。
流量控制
TCP 使用滑动窗口机制进行流量控制,防止发送方发送数据过快,导致接收方缓冲区溢出。
- 接收窗口:接收方在确认应答中会告知发送方自己当前的接收窗口大小,表示接收方缓冲区还能接收多少字节的数据。
- 发送窗口:发送方根据接收方的接收窗口大小调整自己的发送窗口,只发送接收方能够接收的数据量。随着数据的发送和确认,发送窗口和接收窗口会动态滑动。
拥塞控制
为了避免网络拥塞,TCP 采用了多种拥塞控制算法,如慢启动、拥塞避免、快速重传和快速恢复等。
- 慢启动:TCP 连接建立初期,发送方以较小的拥塞窗口(cwnd)开始发送数据,初始 cwnd 通常为 1 个最大报文段(MSS)。每收到一个确认(ACK),cwnd 就增加 1 个 MSS,使发送速率呈指数级增长。
- 拥塞避免:当 cwnd 增长到慢启动阈值(ssthresh)时,进入拥塞避免阶段。在这个阶段,每收到一个 ACK,cwnd 增加 1/cwnd 个 MSS,使 cwnd 呈线性增长。
- 快速重传和快速恢复:当发生快速重传时,执行快速恢复算法。发送方将 ssthresh 设置为当前 cwnd 的一半,同时将 cwnd 设置为 ssthresh 加上 3 倍的 MSS,之后根据收到的确认应答动态调整 cwnd。
校验和
每个 TCP 数据包都包含一个校验和字段,用于检测数据在传输过程中是否发生错误。发送方在发送数据包前,会计算整个 TCP 报文段(包括首部和数据)的校验和,并将其填充到校验和字段中。接收方收到数据包后,会重新计算校验和,并与接收到的校验和进行比较,如果不一致,则认为数据传输有误,会丢弃该数据包,发送方会重传该数据包。
延迟ACK
TCP Delayed ACK(延迟确认)是 TCP 协议中的一种优化机制,用于减少网络中 ACK 报文的数量,提升传输效率。下面从原理、工作机制、优缺点和相关配置等方面详细介绍。
原理
在 TCP 通信中,接收方收到数据后需要向发送方发送 ACK 报文来确认数据的接收。若每收到一个数据包就发送 ACK 报文,会增加网络中报文的数量,占用额外的带宽资源。TCP Delayed ACK 机制允许接收方在收到数据后,不立即发送 ACK 报文,而是等待一段时间,看是否有更多的数据到来,若期间有新数据到达,就可以在一个 ACK 报文中确认多个数据包,从而减少 ACK 报文的发送数量。
工作机制
- 延迟时间:接收方收到数据后,会启动一个延迟定时器,通常这个定时器的时长为 200 毫秒(不同系统可能会有差异)。在定时器超时之前,若接收方有数据要发送给发送方,会在该数据报文中捎带 ACK 信息,确认之前收到的数据;若定时器超时前没有数据要发送,接收方会单独发送 ACK 报文。
- 累计确认:若在延迟期间,接收方又收到多个数据包,会在一个 ACK 报文中对这些数据包进行累计确认,即确认号为下一个期望接收的数据包序列号,从而减少 ACK 报文的发送次数。
- 快速确认:当接收方收到乱序的数据包时,会立即发送 ACK 报文,告知发送方自己期望接收的数据包序列号,以便发送方及时重传丢失的数据包。此外,若接收方连续收到两个按序的数据包,也会立即发送 ACK 报文。
示例场景
假设发送方依次发送数据包 1、2、3,接收方收到数据包 1 后,启动延迟定时器。在定时器超时前,又收到数据包 2 和 3,此时接收方不会为每个数据包单独发送 ACK 报文,而是在定时器超时后,发送一个 ACK 报文,确认号为 4(表示期望接收下一个序列号为 4 的数据包),一次性确认数据包 1、2、3。
优缺点
优点
- 减少网络拥塞:减少 ACK 报文的发送数量,降低网络负载,有助于缓解网络拥塞,特别是在带宽有限的网络环境中。
- 提高传输效率:减少了报文的发送和处理开销,提高了整体的传输效率。
缺点
- 增加延迟:延迟发送 ACK 报文可能会导致发送方等待确认的时间变长,特别是在数据传输量较小、延迟敏感的场景下,会增加端到端的延迟。例如,在交互式应用(如 SSH 会话)中,用户可能会感觉到输入响应变慢。
- 与重传机制相互影响:若延迟时间设置过长,发送方可能会因为未及时收到 ACK 报文而触发重传机制,导致网络中出现重复数据包,浪费网络资源。
相关配置
不同操作系统可以对 TCP Delayed ACK 机制进行配置。
Linux
可以通过修改 /proc/sys/net/ipv4/tcp_delack_min 文件来调整延迟确认的最小时间,单位为毫秒。例如,将最小延迟时间设置为 100 毫秒:
bash
1 | echo 100 > /proc/sys/net/ipv4/tcp_delack_min |
Windows
可以通过注册表修改相关参数。打开注册表编辑器,找到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加或修改 TcpAckFrequency 项,值为 1 表示禁用延迟确认,值为 2 表示启用延迟确认(默认值)。
Nagle算法
TCP Nagle 算法是一种用于优化 TCP 网络性能的算法,由 John Nagle 在 1984 年提出。该算法主要用于减少网络中微小数据包的数量,从而降低网络拥塞,提高网络传输效率。以下从原理、工作机制、优缺点、与其他机制的关系以及代码示例等方面详细介绍。
原理
在网络通信中,若应用程序频繁发送小数据包,会增加网络的负担,因为每个数据包都需要包含 TCP 首部和 IP 首部,这些额外的开销会占据大量带宽。Nagle 算法的核心思想是合并小数据包,将多个小数据包组合成一个较大的数据包进行发送,以此减少网络中的数据包数量。
工作机制
Nagle 算法遵循以下规则:
- 发送第一个数据包:当应用程序第一次发送数据时,无论数据量大小,都会立即发送该数据包。
- 等待确认:在发送第一个数据包后,后续的小数据包(小于最大报文段长度 MSS)不会立即发送,而是会被缓存起来,直到满足以下条件之一:
- 收到上一个数据包的确认应答(ACK):当发送方收到之前发送数据包的 ACK 后,会将缓存中的小数据包组合成一个较大的数据包发送出去。
- 缓存的数据达到最大报文段长度(MSS):如果缓存的数据量达到了 MSS,会立即将这些数据作为一个数据包发送。
- 有紧急数据需要发送:当应用程序有紧急数据需要发送时,会立即发送缓存中的数据。
示例场景
假设应用程序需要发送 4 个小数据包,每个数据包大小为 20 字节,而 MSS 为 100 字节。发送第一个 20 字节的数据包后,后续的 3 个数据包会被缓存起来。当收到第一个数据包的 ACK 后,将缓存的 3 个数据包(共 60 字节)与第一个未发送的小数据包组合成一个 80 字节的数据包发送出去。
优缺点
优点
- 减少网络拥塞:通过合并小数据包,减少了网络中数据包的数量,降低了网络负载,有助于缓解网络拥塞。
- 提高带宽利用率:减少了每个数据包的首部开销,提高了有效数据在总传输数据中的比例,从而提高了带宽利用率。
缺点
- 增加延迟:在等待确认应答的过程中,后续的小数据包会被缓存,导致数据发送延迟。对于实时性要求较高的应用(如实时游戏、SSH 会话),可能会造成用户体验下降。
与其他机制的关系
- 与 TCP Delayed ACK 的关系:TCP Delayed ACK 机制会延迟发送确认应答,这可能会导致 Nagle 算法缓存更多的小数据包,进一步增加延迟。两者相互影响,在某些情况下可能会导致性能问题。
- 与 TCP_NODELAY 选项的关系:大多数操作系统提供了
TCP_NODELAY选项,用于禁用 Nagle 算法。当设置TCP_NODELAY为true时,应用程序发送的每个小数据包都会立即发送,不会被缓存。
滑动窗口
TCP 滑动窗口算法是 TCP 协议中用于流量控制和提高传输效率的关键机制。下面从原理、工作过程、流量控制作用、窗口大小调整等方面详细介绍。
原理
TCP 滑动窗口机制允许发送方在未收到接收方确认(ACK)的情况下,连续发送多个数据包,从而提高网络利用率。发送方和接收方各自维护一个发送窗口和接收窗口,窗口大小表示可以发送或接收的字节数。发送窗口决定了发送方在未收到确认时能发送的数据量,接收窗口则告知发送方接收方当前能够接收的数据量。
工作过程
发送方窗口
发送方窗口由三个部分组成:
- 已发送并已确认:这部分数据已经发送给接收方,并且已经收到接收方的确认,发送方无需再处理。
- 已发送但未确认:数据已经发送,但还未收到接收方的确认,发送方需要等待确认,如果超时未收到确认,可能需要重传。
- 未发送但可发送:发送方可以发送这部分数据,但需要根据接收方的窗口大小和网络状况来决定是否发送。
接收方窗口
接收方窗口也分为两部分:
- 已接收并已确认:这部分数据已经被接收方正确接收并发送了确认信息。
- 准备接收:接收方期望接收的数据,接收方会维护一个接收缓冲区,当有数据到达时,会将其放入缓冲区,然后发送确认信息。
示例
假设发送方和接收方初始窗口大小都为 4 个数据包,序列号从 1 开始。
- 发送数据:发送方发送序列号为 1、2、3、4 的数据包,此时窗口向右滑动,已发送但未确认的部分包含这 4 个数据包。
- 接收确认:接收方收到序列号为 1、2 的数据包后,发送确认信息 ACK 3,表示期望下一个接收的序列号为 3。发送方收到 ACK 3 后,将窗口向右滑动,已发送并已确认的部分包含序列号为 1、2 的数据包,此时可以继续发送序列号为 5、6 的数据包。
流量控制作用
接收方通过接收窗口大小来告知发送方自己的接收能力,发送方根据接收方的窗口大小调整发送窗口,避免发送过多数据导致接收方缓冲区溢出。例如,接收方处理数据速度变慢,缓冲区接近满时,会减小接收窗口大小并通知发送方,发送方相应减小发送窗口,降低发送速率。
窗口大小调整
- 动态调整:窗口大小不是固定不变的,会根据网络状况和接收方的处理能力动态调整。当网络状况良好且接收方处理能力较强时,窗口可以增大,提高传输效率;当网络拥塞或接收方缓冲区接近满时,窗口会减小。
- 窗口通告:接收方在发送确认信息时,会在 TCP 头部的窗口字段中告知发送方自己当前的接收窗口大小,发送方根据这个信息调整发送窗口。
Go 语言示例代码
以下是一个简单的 Go 语言示例,模拟 TCP 滑动窗口的基本原理:
1 | package main |
上述代码模拟了发送方和接收方的交互过程,发送方根据窗口大小发送数据,接收方接收数据并发送确认信息,发送方根据确认信息调整窗口。
拥塞算法
TCP 拥塞控制算法用于在网络出现拥塞时,调节发送方的发送速率,避免网络进一步恶化,保障网络的稳定性和高效性。下面介绍几种常见的 TCP 拥塞控制算法。
1. 慢启动(Slow Start)
- 原理:TCP 连接建立初期,发送方对网络状况不了解,为避免瞬间发送大量数据导致网络拥塞,发送方以较小的拥塞窗口(Congestion Window,cwnd)开始发送数据,初始 cwnd 通常为 1 个最大报文段(MSS)。每收到一个确认(ACK),cwnd 就增加 1 个 MSS。这样,发送方的发送速率呈指数级增长。
- 作用:快速试探网络的承载能力,让发送方逐渐增加发送数据量。
- 示例伪代码
1 | cwnd = 1 * MSS |
2. 拥塞避免(Congestion Avoidance)
- 原理:当 cwnd 增长到慢启动阈值(ssthresh)时,慢启动阶段结束,进入拥塞避免阶段。在这个阶段,发送方不再以指数级增长 cwnd,而是每收到一个 ACK,cwnd 增加 1/cwnd 个 MSS,使 cwnd 呈线性增长,以此更谨慎地试探网络的拥塞状态。
- 作用:防止网络拥塞,在网络接近拥塞点时,平稳地增加发送速率。
- 示例伪代码
1 | while (收到 ACK) { |
3. 快速重传(Fast Retransmit)
- 原理:当发送方连续收到 3 个相同的 ACK 时,表明有数据包丢失,但网络尚未完全拥塞。此时,发送方不等超时重传定时器到期,就立即重传丢失的数据包。
- 作用:快速恢复丢失的数据包,减少等待超时的时间,提高传输效率。
4. 快速恢复(Fast Recovery)
- 原理:在快速重传之后,进入快速恢复阶段。发送方将 ssthresh 设置为当前 cwnd 的一半,同时将 cwnd 设置为 ssthresh 加上 3 倍的 MSS(因为收到 3 个重复 ACK 意味着有 3 个数据包已成功到达接收方)。之后,每收到一个重复 ACK,cwnd 增加 1 个 MSS;收到新的 ACK 时,将 cwnd 设置为 ssthresh,进入拥塞避免阶段。
- 作用:在数据包丢失后,快速调整发送速率,恢复网络传输。
5. TCP Reno
- 原理:结合了慢启动、拥塞避免、快速重传和快速恢复算法。当发生超时重传时,认为网络出现严重拥塞,将 ssthresh 设为当前 cwnd 的一半,cwnd 重置为 1 个 MSS,重新进入慢启动阶段;当发生快速重传时,执行快速恢复算法。
- 特点:是一种广泛使用的 TCP 拥塞控制算法,在大多数网络环境下能较好地平衡传输效率和网络稳定性。
6. TCP New Reno
- 原理:是 TCP Reno 的改进版本,主要改进在于处理多个数据包丢失的情况。在快速恢复阶段,TCP New Reno 能更准确地判断哪些数据包已经丢失并需要重传,避免不必要的重传。
- 特点:在网络丢包率较高的情况下,性能优于 TCP Reno。
7. TCP Vegas
- 原理:基于延迟的拥塞控制算法,通过测量数据包的往返时间(RTT)来估计网络的拥塞程度。发送方维护一个期望的 RTT 和实际的 RTT,当实际 RTT 大于期望 RTT 时,认为网络出现拥塞,降低发送速率;反之则提高发送速率。
- 特点:能更及时地响应网络拥塞变化,但对网络延迟的测量精度要求较高。
8. TCP BBR(Bottleneck Bandwidth and Round - trip propagation time)
- 原理:基于带宽和往返传播时间的拥塞控制算法。BBR 算法尝试测量网络的最大带宽和最小往返时间,通过动态调整发送速率,使发送速率接近网络的最大带宽,同时避免网络拥塞。
- 特点:能在各种网络环境下快速达到网络的最大传输能力,减少排队延迟,提高网络利用率。
HTTP
输入url到页面展示发生了什么
从输入 URL 到页面展示是一个复杂的过程,涉及网络、浏览器等多个环节。下面按照顺序详细介绍主要步骤:
1. URL 解析
用户在浏览器地址栏输入 URL 后,浏览器会先对其进行解析,识别出协议(如 http、https)、域名(如 www.example.com)、端口号(若未指定,HTTP 默认 80,HTTPS 默认 443)、路径(如 /index.html)等信息。
2. DNS 解析
由于计算机网络中使用 IP 地址进行通信,而用户输入的是域名,因此需要将域名转换为对应的 IP 地址,这一过程由 DNS(域名系统)完成。解析流程如下:
- 浏览器缓存:浏览器会先检查自身缓存中是否有该域名对应的 IP 地址,如果有则直接使用。
- 系统缓存:若浏览器缓存中没有,浏览器会检查操作系统的缓存(如 Windows 的
hosts文件)。 - 本地 DNS 服务器:若系统缓存也没有,请求会发送到本地 DNS 服务器。本地 DNS 服务器通常由网络服务提供商(ISP)提供,它有自己的缓存,若缓存中有则返回结果。
- 根 DNS 服务器:若本地 DNS 服务器没有缓存,它会向根 DNS 服务器发起请求。根 DNS 服务器返回顶级域 DNS 服务器(如
.com、.cn等)的地址。 - 顶级域 DNS 服务器:本地 DNS 服务器再向顶级域 DNS 服务器请求,获取权威 DNS 服务器的地址。
- 权威 DNS 服务器:本地 DNS 服务器向权威 DNS 服务器请求,获取最终的 IP 地址,并将结果返回给浏览器,同时可能会将结果缓存起来。
3. 建立 TCP 连接
浏览器获取到目标服务器的 IP 地址后,会通过 TCP 协议与服务器建立连接。TCP 连接使用三次握手过程:
- 第一次握手:客户端(浏览器)向服务器发送一个 SYN 报文,请求建立连接,并携带一个随机序列号
seq=x。 - 第二次握手:服务器收到 SYN 报文后,返回一个 SYN + ACK 报文,确认客户端的请求,包含自己的随机序列号
seq=y和对客户端序列号的确认号ack=x+1。 - 第三次握手:客户端收到 SYN + ACK 报文后,发送一个 ACK 报文,确认服务器的连接请求,确认号
ack=y+1。至此,TCP 连接建立成功。
4. 发起 HTTP 请求
TCP 连接建立后,浏览器会根据解析出的信息构建 HTTP 请求报文,并发送给服务器。请求报文包含请求行(如 GET /index.html HTTP/1.1)、请求头(如 User - Agent、Accept 等)和请求体(对于 POST 请求)。
5. 服务器处理请求
服务器接收到 HTTP 请求后,会根据请求的内容进行处理,可能涉及以下操作:
- 验证请求:检查请求的合法性,如请求方法、请求路径等。
- 处理业务逻辑:根据请求调用相应的应用程序或脚本,进行数据查询、计算等操作。
- 生成响应:将处理结果封装成 HTTP 响应报文,包含响应行(如
HTTP/1.1 200 OK)、响应头(如Content - Type、Content - Length等)和响应体(如 HTML 页面内容)。
6. 浏览器接收响应
服务器将 HTTP 响应报文发送回浏览器,浏览器接收到响应后,首先检查响应状态码,常见状态码如 200 表示请求成功,404 表示页面未找到,301、302 表示重定向。如果是重定向,浏览器会根据响应头中的 Location 字段重新发起请求。
7. 解析渲染页面
浏览器接收到完整的 HTML 响应后,开始解析和渲染页面,主要步骤如下:
- 解析 HTML:浏览器将 HTML 代码解析成 DOM(文档对象模型)树。
- 解析 CSS:同时解析 CSS 代码,构建 CSSOM(CSS 对象模型)树。
- 合成渲染树:将 DOM 树和 CSSOM 树合并成渲染树,渲染树只包含需要显示的节点及其样式信息。
- 布局计算:根据渲染树计算每个节点在屏幕上的位置和大小,这个过程称为布局(Layout)或回流(Reflow)。
- 绘制页面:根据布局结果,将节点绘制到屏幕上,这个过程称为绘制(Paint)。
- 合成层:现代浏览器会将页面分成多个图层,进行合成操作,提高渲染性能。
8. 加载资源
在解析 HTML 过程中,浏览器会遇到 <img>、<script>、<link> 等标签,需要加载对应的外部资源(如图片、脚本、样式表)。浏览器会并行发起多个请求来加载这些资源,加载过程同样遵循上述 DNS 解析、TCP 连接、HTTP 请求等步骤。
9. 执行 JavaScript 脚本
当 HTML 解析到 <script> 标签时,如果是内联脚本则直接执行,如果是外部脚本则等待脚本加载完成后执行。JavaScript 脚本可以操作 DOM 和 CSSOM,可能会触发页面的重新布局和绘制。
10. 页面加载完成
当所有资源加载完成,JavaScript 脚本执行完毕,页面渲染完成,整个加载过程结束。
HTTP和HTTPS的区别
HTTP(Hypertext Transfer Protocol)和 HTTPS(Hypertext Transfer Protocol Secure)都是用于在网络上传输数据的协议,不过 HTTPS 是在 HTTP 基础上增加了安全机制。下面从多个方面介绍两者的区别:
1. 安全性
- HTTP:是明文传输协议,数据在传输过程中以明文形式存在,容易被中间人拦截、窃取和篡改。例如,在公共 Wi-Fi 环境下,攻击者可以通过抓包工具获取用户的账号、密码等敏感信息。
- HTTPS:基于 SSL/TLS 协议对数据进行加密传输,能够有效防止数据在传输过程中被窃取和篡改。即使数据被拦截,攻击者没有私钥也无法解密获取其中的内容。
2. 连接方式
- HTTP:使用 80 端口,直接和服务器建立 TCP 连接,传输数据时不进行加密处理。
- HTTPS:默认使用 443 端口,在建立 TCP 连接后,还需要进行 SSL/TLS 握手过程,协商加密算法、交换密钥等,之后再进行加密数据传输。
3. 证书
- HTTP:不需要证书,任何服务器都可以搭建 HTTP 服务。
- HTTPS:需要 SSL/TLS 证书,该证书由受信任的证书颁发机构(CA)签发。服务器部署证书后,浏览器访问时会验证证书的有效性,以确认服务器的身份,防止中间人攻击。证书分为免费和付费两种,付费证书通常更受信任,且有更高的安全级别。
4. 性能
- HTTP:由于没有加密和解密过程,数据传输速度相对较快,服务器开销较小。
- HTTPS:SSL/TLS 握手过程会增加连接建立的时间,加密和解密操作也会消耗一定的 CPU 和内存资源,导致性能有所下降。不过,随着硬件性能的提升和加密算法的优化,HTTPS 的性能损耗在逐渐减小。
5. 搜索引擎优化(SEO)
- HTTP:搜索引擎对其信任度相对较低,在搜索排名中可能不占优势。
- HTTPS:各大搜索引擎(如 Google、百度)都更青睐使用 HTTPS 的网站,会给予一定的搜索排名权重,有助于提高网站的曝光度。
6. 应用场景
- HTTP:适用于对安全性要求不高的场景,如一些静态资源的访问,或者内部网络环境下的简单应用。
- HTTPS:适用于涉及用户敏感信息传输的场景,如电商网站的支付页面、在线银行的登录页面、用户注册登录页面等。
示例代码(Go 语言实现简单 HTTP 和 HTTPS 服务器)
HTTP 服务器
1 | package main |
HTTPS 服务器
1 | package main |
综上所述,HTTPS 在安全性方面有显著优势,随着网络安全意识的提高,越来越多的网站选择使用 HTTPS 协议。
HTTPS建连过程
HTTPS 建连握手过程主要是在 TCP 连接建立之后,通过 SSL/TLS 协议来保障数据传输的安全性。下面以 TLS 1.3 版本为例,详细介绍其握手过程,TLS 1.3 相比之前版本有性能优化和安全性提升。
1. TCP 连接建立
在进行 HTTPS 握手前,需要先建立 TCP 连接,使用三次握手机制:
- 第一次握手(SYN):客户端向服务器发送一个 SYN 报文,包含客户端随机数
Client Random和自身支持的最大 TCP 窗口大小等信息,表明希望建立连接。 - 第二次握手(SYN + ACK):服务器收到 SYN 报文后,返回 SYN + ACK 报文。其中 SYN 包含服务器随机数
Server Random,ACK 是对客户端 SYN 的确认,确认号为客户端序列号加 1。 - 第三次握手(ACK):客户端收到服务器的 SYN + ACK 报文后,发送 ACK 报文确认,确认号为服务器序列号加 1,至此 TCP 连接建立完成。
2. TLS 1.3 握手过程
客户端 Hello(Client Hello)
客户端向服务器发送 Client Hello 消息,包含以下关键信息:
- TLS 版本:客户端支持的最高 TLS 版本,如 TLS 1.3。
- 随机数:客户端生成的随机数
Client Random。 - 加密套件列表:客户端支持的加密套件组合,例如
TLS_AES_128_GCM_SHA256等。 - 密钥共享参数:客户端发送自己的公钥(基于椭圆曲线算法,如 X25519),用于后续的密钥交换。
- 扩展信息:包含一些额外的配置信息,比如支持的证书类型、签名算法等。
服务器 Hello(Server Hello)
服务器收到 Client Hello 消息后,回复 Server Hello 消息,内容如下:
- TLS 版本:服务器选定的 TLS 版本,通常是客户端支持版本中的最高版本。
- 随机数:服务器生成的随机数
Server Random。 - 加密套件:服务器从客户端提供的加密套件列表中选择一个加密套件。
- 密钥共享参数:服务器发送自己的公钥,与客户端的公钥配合生成预主密钥。
- 会话票证(Session Ticket):可选,用于后续的会话恢复,提升连接速度。
服务器加密参数(Encrypted Extensions)
服务器发送 Encrypted Extensions 消息,包含一些需要加密传输的扩展信息,比如服务器支持的应用层协议(ALPN)等。
服务器证书(Certificate)
服务器将自己的 SSL/TLS 证书发送给客户端,证书包含服务器公钥、证书颁发机构(CA)信息、有效期等。客户端会验证证书的有效性,检查证书链、有效期、是否被吊销等。
服务器证书验证(Certificate Verify)
服务器发送 Certificate Verify 消息,使用私钥对之前握手消息的摘要进行签名,客户端可以使用证书中的公钥验证签名,确保消息的完整性和服务器身份的真实性。
服务器完成(Finished)
服务器发送 Finished 消息,该消息经过加密,包含对之前握手消息的验证数据,用于客户端验证握手过程是否被篡改。
客户端证书(Certificate,可选)
如果服务器要求客户端进行双向认证,客户端会发送自己的证书给服务器,服务器对证书进行验证。
客户端证书验证(Certificate Verify,可选)
若客户端发送了证书,会发送 Certificate Verify 消息,使用私钥对握手消息摘要签名,供服务器验证。
客户端完成(Finished)
客户端发送 Finished 消息,同样经过加密,包含对握手过程的验证数据,服务器验证该消息后,双方确认握手成功。
3. 密钥生成
在握手过程中,客户端和服务器利用 Client Random、Server Random 以及双方交换的公钥,通过椭圆曲线 Diffie - Hellman(ECDH)算法生成预主密钥(Pre - Master Secret),再由预主密钥生成主密钥(Master Secret),最后基于主密钥生成会话密钥,用于后续数据的加密和解密。
4. 数据传输
握手完成后,客户端和服务器使用协商好的加密套件和会话密钥对应用层数据进行加密传输,保障数据的机密性和完整性。
TLS 1.3 握手优化
TLS 1.3 相比旧版本减少了握手的往返次数,在大多数情况下,只需要 1 个往返(1 - RTT)就能完成握手并开始数据传输,提升了连接效率。
HTTP1和HTTP2的区别
HTTP/1 和 HTTP/2 是 HTTP 协议发展过程中的两个重要版本,HTTP/2 对 HTTP/1 进行了多方面的改进和优化,以下是两者的主要区别:
1. 连接模型
- HTTP/1
- 短连接:默认情况下,每次请求 - 响应完成后连接就会关闭。若要复用连接,需要在请求头中设置
Connection: keep - alive,即便如此,同一时间一个 TCP 连接只能处理一个请求,后续请求需等待前一个请求完成。 - 长连接:虽然可通过
keep - alive实现长连接,但在高并发场景下,为了提高性能,客户端往往会建立多个 TCP 连接来处理多个请求,这会增加服务器的资源消耗和网络拥塞的可能性。
- 短连接:默认情况下,每次请求 - 响应完成后连接就会关闭。若要复用连接,需要在请求头中设置
- HTTP/2
- 多路复用:使用单一的 TCP 连接处理多个请求和响应,不同的请求和响应可以在这个连接上并行传输,互不干扰。每个请求和响应都有独立的流 ID,通过流 ID 进行区分和管理,避免了 HTTP/1 中的队头阻塞问题,提高了连接的利用率和性能。
2. 头部压缩
- HTTP/1
- 每次请求和响应都会携带完整的头部信息,即使大部分头部字段的值在多次请求中保持不变,也会重复传输,造成了带宽的浪费。
- HTTP/2
- 采用 HPACK 算法对头部进行压缩。该算法会维护一个静态表和动态表,静态表包含常见的头部字段和值,动态表会根据实际传输的头部信息动态更新。传输时,只需要传输头部字段的索引或增量信息,大大减少了头部的传输大小,节省了带宽。
3. 数据传输格式
- HTTP/1
- 采用纯文本格式传输数据,请求和响应的各个部分(如请求行、头部、消息体)通过换行符分隔,这种格式易于人类阅读和调试,但不利于机器高效处理。
- HTTP/2
- 采用二进制分帧层,将所有传输的信息分割为更小的帧(Frame),并对帧进行二进制编码。帧有不同的类型,如数据帧、头部帧等,这种二进制格式更高效、更紧凑,便于机器解析和处理。
4. 服务器推送
- HTTP/1
- 客户端发起请求,服务器被动响应,服务器无法主动向客户端推送资源。客户端需要在解析 HTML 页面后,发现引用的资源(如 CSS、JavaScript 文件),再分别发起请求获取这些资源。
- HTTP/2
- 支持服务器推送功能。服务器可以在客户端请求一个资源时,主动将该资源依赖的其他资源(如 CSS 文件、图片等)推送给客户端,客户端将这些资源缓存起来,减少后续请求的等待时间,提高页面加载速度。
5. 优先级设置
- HTTP/1
- 没有明确的优先级机制,客户端无法向服务器表明请求的优先级,服务器按请求到达的顺序依次处理。
- HTTP/2
- 允许客户端为每个请求设置优先级,服务器可以根据优先级来决定资源的传输顺序,优先处理高优先级的请求,提高关键资源的加载速度。
6. 安全性
- HTTP/1
- 本身不强制要求使用加密传输,虽然可以通过 HTTPS(基于 SSL/TLS 的 HTTP)实现安全传输,但并非默认配置。
- HTTP/2
- 虽然规范中没有强制要求,但在实际应用中,大多数浏览器只支持在 HTTPS 上使用 HTTP/2,因此 HTTP/2 通常伴随着更高的安全性。
示例代码对比(使用 Go 语言创建简单服务器)
HTTP/1 服务器
1 | package main |
HTTP/2 服务器
1 | package main |
综上所述,HTTP/2 在性能、效率和安全性等方面相比 HTTP/1 有显著提升,能更好地满足现代 Web 应用的需求。
HTTP3
HTTP/3 是 HTTP 协议的第三个主要版本,它基于 QUIC(Quick UDP Internet Connections)协议构建,旨在进一步提升网络传输性能和用户体验。以下从多个方面详细介绍 HTTP/3。
协议背景
HTTP/1 存在队头阻塞、头部未压缩等问题,HTTP/2 虽通过多路复用、头部压缩等特性进行了优化,但基于 TCP 协议,仍存在 TCP 层面的队头阻塞问题。而 HTTP/3 采用 UDP 作为传输层协议,结合 QUIC 协议,解决了这些问题。
关键特性
1. 基于 QUIC 协议
- 快速握手:QUIC 协议在首次连接时能实现 1 - RTT(Round - Trip Time)完成握手,后续连接甚至可以 0 - RTT 完成,相比 TCP + TLS 的握手方式,减少了往返时间,加快了连接建立速度。
- 多路复用:与 HTTP/2 类似,支持多路复用,但由于基于 UDP,不同流之间不会相互影响。在 TCP 中,一个数据包丢失会导致整个连接阻塞,而在 QUIC 中,某个流的数据包丢失只会影响该流,其他流能正常传输。
2. 解决队头阻塞问题
- 传输层层面:TCP 协议中,若一个数据包丢失,后续的数据包即使已到达接收端,也需要等待丢失的数据包重传后才能按序交付,这就是 TCP 队头阻塞。QUIC 协议基于 UDP 实现,每个流都是独立的,一个流的数据包丢失不会影响其他流的数据传输,避免了传输层的队头阻塞。
- 应用层层面:HTTP/3 继承了 HTTP/2 的二进制分帧特性,在应用层也能高效处理数据,进一步提升传输效率。
3. 连接迁移
- 在移动场景下,设备可能会在不同网络(如 Wi - Fi 和 4G)间切换,TCP 连接依赖于源 IP 地址、源端口、目标 IP 地址和目标端口,网络切换会导致 IP 地址变化,从而使 TCP 连接中断,需要重新建立连接。而 QUIC 协议通过连接 ID 来标识连接,即使 IP 地址或端口发生变化,只要连接 ID 不变,连接就能保持,实现无缝的连接迁移。
4. 加密传输
- QUIC 协议内置了加密机制,使用 TLS 1.3 进行加密,保证数据传输的安全性。这意味着 HTTP/3 天然具备加密能力,无需像 HTTP/1 那样额外配置 HTTPS 来实现安全传输。
5. 流量控制和拥塞控制
- 流量控制:QUIC 为每个流和整个连接都提供了流量控制机制,防止接收方因处理能力不足而被过多数据淹没。
- 拥塞控制:QUIC 支持多种拥塞控制算法,并且可以在运行时动态切换,能更好地适应不同的网络环境。
与 HTTP/2 的对比
1. 性能提升
- 连接建立:HTTP/3 首次连接 1 - RTT 完成,后续 0 - RTT;HTTP/2 基于 TCP + TLS,首次连接通常需要 2 - 3 RTT。
- 传输效率:HTTP/3 解决了 TCP 队头阻塞问题,在网络状况不佳时,传输效率优势更明显。
2. 安全性
- HTTP/3 基于 QUIC 内置 TLS 1.3 加密,安全性有保障;HTTP/2 虽然常与 HTTPS 搭配使用,但并非强制。
3. 兼容性
- HTTP/3 是较新的协议,部分旧设备和网络中间件可能不支持;HTTP/2 已经得到广泛支持,兼容性更好。
浏览器支持情况
主流浏览器如 Chrome、Firefox、Safari 等都已支持 HTTP/3,随着网络基础设施的升级和协议的推广,HTTP/3 的普及率会逐渐提高。
示例代码(使用 Go 语言创建 HTTP/3 服务器)
1 | package main |
上述代码使用 github.com/lucas-clemente/quic-go/http3 库创建了一个简单的 HTTP/3 服务器,运行前需要准备有效的证书文件和私钥文件。
Websocket
WebSocket 是一种在单个 TCP 连接上进行全双工通信的网络协议,于 2011 年被 IETF 定为标准 RFC 6455,主要用于解决传统 HTTP 协议在实时通信场景下的局限性。以下从多个方面详细介绍 WebSocket 协议。
1. 产生背景
传统的 HTTP 协议是半双工、无状态的,客户端发起请求,服务器响应请求,这种模式在实现实时通信(如即时聊天、在线游戏、实时数据更新等)时,需要频繁建立和断开连接,或者使用轮询、长轮询等技术,但这些方式会增加服务器负担和网络开销,且实时性较差。WebSocket 应运而生,提供了高效、实时的双向通信能力。
2. 协议特点
- 全双工通信:客户端和服务器可以在任何时刻相互发送数据,无需等待对方的请求,实现真正的实时通信。
- 单 TCP 连接:WebSocket 基于单个 TCP 连接进行通信,连接建立后可长期保持,减少了频繁建立和断开连接的开销。
- 低开销:数据传输时头部信息较小,相比 HTTP 协议,能节省带宽资源。
- 跨域支持:通过合适的配置,WebSocket 可以实现跨域通信。
- 与 HTTP 兼容:WebSocket 握手阶段使用 HTTP 协议,端口也与 HTTP/HTTPS 相同(默认 80 和 443),便于在现有网络基础设施中部署。
3. 握手过程
WebSocket 连接建立需要经过 HTTP 握手阶段,具体步骤如下:
- 客户端发起握手请求:客户端发送一个类似 HTTP 的请求,请求头中包含
Upgrade和Connection字段,表明希望将连接升级为 WebSocket 协议。示例请求如下:
1 | GET /chat HTTP/1.1 |
- 服务器响应:服务器收到请求后,验证请求的合法性,如果同意升级,返回一个状态码为
101 Switching Protocols的响应,同时包含Upgrade和Connection字段,以及Sec-WebSocket-Accept字段(对客户端Sec-WebSocket-Key进行特定计算后的结果)。示例响应如下:
1 | HTTP/1.1 101 Switching Protocols |
- 连接建立:客户端收到服务器响应后,验证
Sec-WebSocket-Accept字段,如果验证通过,WebSocket 连接建立成功,双方可以开始进行全双工通信。
4. 数据帧格式
WebSocket 数据以帧(Frame)为单位进行传输,每个帧包含以下部分:
- FIN:1 位,表示该帧是否是消息的最后一帧。
- RSV1 - RSV3:各 1 位,通常用于扩展协议,默认值为 0。
- Opcode:4 位,表示帧的类型,常见类型有文本帧(0x01)、二进制帧(0x02)、关闭帧(0x08)等。
- Mask:1 位,表示数据是否进行掩码处理,客户端发送的数据必须进行掩码处理。
- Payload length:7 位、7 + 16 位或 7 + 64 位,表示数据负载的长度。
- Masking - key:32 位,当
Mask为 1 时存在,用于对数据进行掩码处理。 - Payload data:实际传输的数据。
5. 关闭连接
当一方想要关闭连接时,会发送一个关闭帧,包含关闭状态码和可选的关闭原因。另一方收到关闭帧后,也发送一个关闭帧作为响应,然后双方关闭 TCP 连接。常见的关闭状态码有 1000(正常关闭)、1001(端点离开)等。
6. 应用场景
- 即时通讯:如在线聊天、客服系统等,实现消息的实时收发。
- 实时数据推送:股票行情、体育赛事比分等数据的实时更新。
- 在线游戏:实现玩家之间的实时交互和游戏状态同步。
SSE
Server-Sent Events(SSE)是一种 Web 浏览器与服务器之间实现服务器到客户端单向通信的 Web API,它允许服务器在客户端建立连接后,持续向客户端推送更新数据。下面从多个方面详细介绍 SSE 协议。
1. 产生背景
在 Web 应用中,很多场景需要服务器主动向客户端推送数据,如实时新闻更新、股票价格变动等。传统的 HTTP 协议是客户端发起请求,服务器响应,无法满足服务器主动推送的需求。虽然 WebSocket 可以实现双向通信,但对于只需要服务器单向推送数据的场景,使用 WebSocket 会带来一定的复杂性。SSE 应运而生,提供了一种简单高效的服务器单向推送方案。
2. 协议特点
- 单向通信:SSE 是服务器到客户端的单向通信,服务器可以主动向客户端推送数据,而客户端只能通过发起新的 HTTP 请求与服务器交互。
- 基于 HTTP 协议:SSE 基于 HTTP 协议,不需要像 WebSocket 那样进行复杂的握手过程,易于实现和部署。
- 自动重连:如果连接中断,客户端会自动尝试重新连接服务器,恢复数据接收。
- 文本格式:SSE 传输的数据以文本格式发送,易于阅读和调试。
3. 工作原理
客户端通过发起一个 HTTP 请求与服务器建立连接,请求的 Accept 头设置为 text/event-stream,表示客户端希望接收服务器发送的事件流。服务器收到请求后,返回一个状态码为 200 的响应,响应头的 Content-Type 设置为 text/event-stream,并保持连接打开,持续向客户端发送事件数据。
4. 数据格式
SSE 数据以文本行的形式发送,每行以特定的字段开头,常见字段如下:
data:用于指定事件的数据内容。如果数据有多行,可以使用多个data字段,每个字段对应一行数据。event:用于指定事件的类型,客户端可以根据事件类型进行不同的处理。如果未指定,默认为message。id:用于指定事件的唯一标识符,客户端可以使用该标识符在重连时请求从指定的事件开始接收数据。retry:用于指定客户端在连接中断后,重新连接的时间间隔(单位:毫秒)。
示例 SSE 数据:
1 | event: news |
5. 与 WebSocket 的对比
- 通信方向:SSE 是单向通信,仅支持服务器向客户端推送数据;WebSocket 是双向通信,客户端和服务器可以随时相互发送数据。
- 协议复杂度:SSE 基于 HTTP 协议,实现简单;WebSocket 需要进行专门的握手过程,协议相对复杂。
- 数据格式:SSE 以文本格式传输数据;WebSocket 支持文本和二进制数据传输。
- 适用场景:SSE 适用于服务器单向推送数据的场景,如实时新闻、股票行情等;WebSocket 适用于需要双向实时通信的场景,如在线聊天、多人游戏等。