当前位置: 首页 > news >正文

websocket网络通信协议

websocket网络通信协议

参考:websocket_rfc6455

网络:

  • 网络编程:解决1对多通信问题(1个server对N个client)
    • epoll
    • reactor
  • 网络协议:解决一个客户端与一个服务器的通信问题
    • http
    • websocket

websocket

基于tcp的协议,解决粘包和拆包问题.

websocket头

WebSocket 的头信息结构需区分握手阶段(基于 HTTP 协议)和数据传输阶段(WebSocket 帧格式),两者的结构差异较大:

一、握手阶段:基于 HTTP 头信息

WebSocket 握手是通过 HTTP 协议完成的(客户端发送 HTTP 请求,服务器返回 HTTP 响应),因此头信息遵循 HTTP 格式,核心字段如下:

1. 客户端握手请求头(HTTP GET 请求)
GET /chat HTTP/1.1
Host: example.com:8080
Upgrade: websocket                  // 核心:请求升级到 WebSocket 协议
Connection: Upgrade                 // 配合 Upgrade,表示连接要升级
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==  // 随机字符串,用于服务器验证
Sec-WebSocket-Version: 13           // 客户端支持的 WebSocket 版本(当前标准为 13)
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits  // 可选:协商扩展(如压缩)
Sec-WebSocket-Protocol: chat, superchat  // 可选:协商子协议(应用层自定义协议)
Origin: http://example.com          // 可选:客户端来源(用于服务器跨域验证)

关键字段说明:

  • Upgrade: websocket + Connection: Upgrade:强制触发 HTTP 协议升级机制,声明要从 HTTP 切换到 WebSocket。
  • Sec-WebSocket-Key:16 字节随机值的 Base64 编码,用于服务器生成 Sec-WebSocket-Accept 进行验证(防止误判非 WebSocket 响应)。
  • Sec-WebSocket-Version: 13:指定 WebSocket 版本(13 是当前标准,早期版本如 8、10 已淘汰)。
2. 服务器握手响应头(101 状态码)
HTTP/1.1 101 Switching Protocols    // 核心:确认协议升级
Upgrade: websocket                  // 呼应客户端,确认升级到 WebSocket
Connection: Upgrade                 // 确认连接保持升级状态
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=  // 服务器验证后的密钥(基于客户端 Key + GUID 计算)
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits  // 可选:确认支持的扩展
Sec-WebSocket-Protocol: chat        // 可选:确认使用的子协议(从客户端请求中选择)

关键字段说明:

  • 101 Switching Protocols:HTTP 状态码,表示服务器同意协议升级。
  • Sec-WebSocket-Accept:服务器通过“客户端 Key + 固定 GUID(258EAFA5-E914-47DA-95CA-C5AB0DC85B11)”拼接后,经 SHA-1 哈希 + Base64 编码生成,客户端会验证此值以确认服务器支持 WebSocket。

二、数据传输阶段:WebSocket 帧(Frame)头结构

握手完成后,数据传输使用二进制帧格式,每个帧的头信息是二进制结构(而非文本 HTTP 头),格式如下(单位:bit):

字段位数含义
FIN1是否为“最后一帧”:1 = 该帧是消息的最后一部分;0 = 后续还有帧(用于分片消息)。
RSV1-31-1-1保留位,用于扩展协议(如压缩),未使用时必须为 0,否则接收方会断开连接。
Opcode4帧类型:
- 0x0:延续帧(分片消息的中间帧)
- 0x1:文本帧(数据为 UTF-8 编码)
- 0x2:二进制帧(任意二进制数据)
- 0x8:关闭连接帧
- 0x9:Ping 帧(心跳检测)
- 0xA:Pong 帧(Ping 响应)
Mask1是否使用掩码:1 = 帧数据被掩码加密(客户端发送的帧必须设为 1);0 = 未加密(服务器发送的帧必须设为 0)。
Payload Length7 / 7+16 / 7+64有效载荷(数据)长度:
- 若值 ≤ 125:直接表示长度(单位:字节)。
- 若值 = 126:后续 2 字节(16 位无符号整数)表示长度。
- 若值 = 127:后续 8 字节(64 位无符号整数)表示长度。
Masking Key0 / 32掩码密钥:仅当 Mask=1 时存在(4 字节),用于解密 Payload Data(客户端发送的数据必须用此密钥加密)。
Payload Data可变实际传输的数据(文本/二进制/控制信息),长度由 Payload Length 指定。
帧头示例(简化):

假设客户端发送一个 10 字节的文本帧(完整消息,非分片):

  • FIN=1(最后一帧)
  • RSV1-3=000(无扩展)
  • Opcode=0x1(文本帧)
  • Mask=1(客户端发送,需掩码)
  • Payload Length=10(≤125,直接表示)
  • Masking Key=0x12345678(4 字节随机密钥)
  • Payload Data=10字节文本数据(经掩码加密)

总结

WebSocket 的“头信息”分两个阶段:

  1. 握手阶段:基于 HTTP 文本头,核心是通过 Upgrade 等字段完成协议升级和验证(确保双方支持 WebSocket)。
  2. 数据阶段:使用二进制帧头,通过 FINOpcodePayload Length 等字段定义数据传输规则(如消息分片、数据类型、长度等),并通过掩码保证客户端发送数据的安全性。

这种设计既兼容了 HTTP 基础设施(握手阶段),又实现了高效的全双工数据传输(帧结构阶段)。

websocket面试题

为什么websocket要握手?

WebSocket 握手(Handshake)是从 HTTP 协议“升级”到 WebSocket 协议的关键过程,其核心目的是在 HTTP 基础设施(如代理、防火墙、服务器)的兼容前提下,建立一个持久化的全双工通信通道。你提到的“版本升级”“兼容 HTTP 协议”“验证双方身份”是核心原因,具体细节如下:

1. 本质是“协议版本升级”:从 HTTP 到 WebSocket

HTTP 是请求-响应模式的短连接协议(每次通信需客户端主动发起请求),而 WebSocket 是全双工的长连接协议(客户端和服务器可随时双向发送数据)。两者的通信模式完全不同,因此需要通过“握手”完成协议切换:

  • 客户端发送HTTP 升级请求,明确告知服务器:“我想从 HTTP 切换到 WebSocket 协议”,并携带 WebSocket 相关参数(如版本号、支持的扩展等)。
  • 服务器若支持 WebSocket,会返回101 Switching Protocols响应,确认“同意升级”,从此连接不再遵循 HTTP 规则,而是使用 WebSocket 帧格式传输数据。

这一步是“版本升级”的核心:通过 HTTP 协议的“Upgrade”机制,完成从短连接到长连接、从单向请求到双向通信的转换。

2. 兼容 HTTP 协议:穿透现有网络基础设施

WebSocket 设计时必须兼容现有基于 HTTP 的网络环境(如代理服务器、负载均衡器、防火墙等),否则会被这些中间设备拦截或误处理。握手的关键作用就是“伪装”成 HTTP 流量,通过基础设施的验证:

  • 握手过程完全使用 HTTP 报文格式(如 GET 请求方法、Host 头、Upgrade 头),让中间设备误认为这是一个普通 HTTP 请求,从而允许其通过。
  • 只有完成握手后,通信才切换到 WebSocket 帧格式,但此时连接已建立,中间设备通常不会再拦截长连接的后续数据。

若没有握手过程,直接使用全新的协议格式,会被大多数 HTTP 代理/防火墙阻断(它们只允许 HTTP 标准流量),导致 WebSocket 无法在现有网络中普及。

3. 验证双方“协议能力”:确保通信参数一致

握手过程包含简单的“验证机制”,核心是确认双方都理解并支持 WebSocket 协议,避免误连接(如客户端连接到不支持 WebSocket 的 HTTP 服务器):

  • 客户端发送 Sec-WebSocket-Key(一个随机字符串),服务器需通过特定算法(SHA-1 哈希 + Base64 编码)计算出 Sec-WebSocket-Accept 并返回。
  • 客户端验证服务器返回的 Sec-WebSocket-Accept 是否正确,若正确则确认“服务器确实支持 WebSocket”,否则断开连接。

这个验证不是“身份认证”(不涉及用户身份),而是“协议能力验证”,确保双方在同一套规则下通信。此外,握手时还会协商:

  • WebSocket 版本(Sec-WebSocket-Version),避免版本不兼容;
  • 支持的扩展(Sec-WebSocket-Extensions)和子协议(Sec-WebSocket-Protocol),确定数据压缩、自定义协议等细节。
总结

WebSocket 握手是一个“一举三得”的设计:

  • 通过协议升级,从 HTTP 短连接转换为 WebSocket 长连接;
  • 借助HTTP 兼容,穿透现有网络基础设施(代理、防火墙等);
  • 通过协议验证,确保双方支持相同的 WebSocket 规则,避免无效连接。

这使得 WebSocket 既能享受长连接全双工的优势,又能在现有 HTTP 生态中无缝部署,成为实时通信(如聊天、弹幕、实时数据更新)的主流方案。

websocket握手为什么要GUID?

避免数据太短,无法hash.

WebSocket 握手过程中引入固定 GUID(258EAFA5-E914-47DA-95CA-C5AB0DC85B11)的核心目的,并非单纯“避免数据太短无法哈希”,而是通过标准化的固定字符串,确保握手验证的唯一性和安全性,防止“误判”或“跨协议攻击”

具体背景:握手验证的流程

WebSocket 握手的验证逻辑是:

  1. 客户端生成一个 16 字节的随机值,用 Base64 编码后作为 Sec-WebSocket-Key 发送给服务器。
  2. 服务器将这个 Sec-WebSocket-Key 与固定 GUID 拼接,得到一个新字符串。
  3. 对新字符串做 SHA-1 哈希,再将哈希结果用 Base64 编码,得到 Sec-WebSocket-Accept,返回给客户端。
  4. 客户端重复服务器的计算过程,验证返回的 Sec-WebSocket-Accept 是否一致,一致则确认握手成功。
GUID 的核心作用:防止“误匹配”

如果没有这个固定 GUID,验证逻辑会存在严重漏洞:

  • 假设客户端发送的 Sec-WebSocket-Key 是一个随机字符串,服务器只需对其进行某种哈希处理后返回。
  • 但此时可能出现**“巧合匹配”**:比如客户端误将一个普通 HTTP 服务器的响应(非 WebSocket 握手)当作 valid 验证结果(例如,服务器返回的某个字符串恰好与客户端的哈希计算结果一致)。

而固定 GUID 的引入,相当于给验证过程加了一个**“唯一标识符”**:

  • 只有知道这个 GUID 的服务器(即真正支持 WebSocket 协议的服务器),才能生成正确的 Sec-WebSocket-Accept
  • 普通 HTTP 服务器或其他协议的服务器不知道这个 GUID,无法生成匹配的响应,客户端就能明确区分“真正的 WebSocket 服务器”和“其他服务器”。
关于“数据长度”的补充

客户端发送的 Sec-WebSocket-Key 是 16 字节随机值(Base64 编码后为 24 字符),这个长度本身足够进行 SHA-1 哈希(SHA-1 可处理任意长度数据,哪怕只有 1 字节)。

因此,“避免数据太短”是次要因素,真正核心是通过固定 GUID 确保验证逻辑的“协议唯一性”——只有遵循 WebSocket 标准的服务器才能通过验证,从根本上杜绝跨协议的误判风险。

总结

WebSocket 握手引入固定 GUID,是为了给验证过程增加一个**“协议专属密钥”**:

  • 确保服务器确实理解 WebSocket 协议(知道这个 GUID),而非其他协议的服务器。
  • 彻底避免因随机巧合导致的“误验证”,保证握手的安全性和准确性。

这个设计让 WebSocket 在兼容 HTTP 基础设施的同时,又能可靠地区分协议类型,是协议设计中“安全性与兼容性平衡”的典型案例。

http://www.dtcms.com/a/419339.html

相关文章:

  • 佛山网站建设的大品牌wordpress远程写作
  • 网站建设的可用性yw55523can优物入口4虎
  • 如何将网站从建站服务商转移出来
  • 使用C#将Markdown转换为Word或PDF:高效文档转换的利器
  • 做淘宝优惠网站坪山网站建设行情
  • c 做网站流程做视频网站的空间
  • 2025 随身 WiFi 行业报告:格行 WiFi6 技术下放百元市场,中兴华为机型竞争力分析;五款机型芯片方案 / 网速 / 质保深度横评
  • Hi3861 OpenHarmony鸿蒙开发(嵌入式方向) (一)
  • Python常用内建模块——XML
  • mapper.xml中limit分页参数不能使用计算表达式问题
  • 精读C++设计模式20 —— 结构型设计模式:桥接模式
  • AI+传统工作流:Photoshop/Excel的智能插件开发指南
  • 冀州网站制作沈阳网站建设索王道下拉
  • java设计模式:抽象工厂模式 + 建造者模式
  • ps做 网站教程服装花型图案设计网站
  • 指令集、立即数和伪指令
  • 危机领导力:突发事件中的决策与沟通策略
  • Unity学习之垃圾回收GC
  • 五次样条速度规划方法介绍
  • 找人做网站被骗怎么办wordpress 评论 姓名
  • 如何建立公司企业网站社区网站建设方案ppt
  • 解密C++多态:一篇文章掌握精髓
  • Git 进阶指南:深入掌握 git log 查看提交历史
  • C++ 引用协程
  • 淄博企业网站设计公司网页无法打开怎么办
  • 添加测试设备到苹果开发者平台
  • 填坑:VC++ 采用OpenSSL 3.0接口方式生成RSA密钥
  • 郑州做网站的网站再就业技能培训班
  • Vscode 连接服务时候一直出现setting ssh Host server
  • 全面解析数据库审批平台:主流工具对比与选型指南