c++ - 如何解释浏览器的 Sec-websocket-key 用于服务器握手?

标签 c++ websocket

我已经用 C++ 编写了一个支持常规网站的基本 HTTP 服务器,但现在我正在尝试扩展它以支持 websockets。所有的网络和解析都是由我自己的代码完成的,所以没有库——除了我复制并粘贴了一些用于计算 SHA1 和转换为 base64 的代码。

我正在阅读一些描述如何握手传入 websocket 连接的指南,例如:http://www.altdev.co/2012/01/23/writing-your-own-websocket-server/http://enterprisewebbook.com/ch8_websockets.html

我被困在服务器需要从客户端的 header 中获取 key 并将魔术字符串附加到其上的部分,然后使用 SHA1 对其进行哈希处理,将其编码为 base64,并将结果作为接受的一部分发回标题。

给我带来麻烦的具体部分是 key 中的“==”,以及服务器发回的结果字符串中的“=”。我找不到任何说明如何处理这些的信息——我是在将魔术字符串附加到它之前从键中删除 == ,还是让它们保持打开状态?此外,我无法弄清楚最终服务器答案末尾的“=”从何而来——以及为什么服务器的答案只有一个“=”而客户端的 key 有两个“=”

最后,我很困惑为什么服务器使用的魔术字符串是 base16,但客户端浏览器发送的 key 已经是 base64——我是否需要在附加之前将服务器字符串转换为 base 64,或者不需要没关系?

当我转换为 base 64 时,我是将其转换为好像每个 ascii 符号都是数字(因此字符串中的“A”将是 10),还是将整个字符串的二进制表示转换为字符串表示原始二进制但带有 base64 的数字?

很抱歉,如果这是一个愚蠢的问题,但我并没有做过多少网络编程,所以当文章假设读者对部分信息有所了解时,我会感到困惑。

最佳答案

伪代码:

key_decoded = base64_decode(key64)
magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
response = SHA1(append(key_decoded, magic))
response_encoded = base64_encode(response)

base64 编码数据末尾的“=”用于将数据填充到所需的长度。您无需对其进行任何操作。 (参见此处:Why does a base64 encoded string have an = sign at the end)不同长度的输入数据可能需要不同的填充量,因此在您的示例中,两个编码值具有不同的填充量。

当您转换为 base64 时,您不会对输入数据做出任何假设,它只是输入字节。不要将 'a' 转换为 10(您似乎认为 ascii 字符应该代表十六进制数字,这是不相关的)

关于c++ - 如何解释浏览器的 Sec-websocket-key 用于服务器握手?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24460390/

相关文章:

c++ - std::sort 中的崩溃 - 没有严格弱排序的排序

javascript - 即使在支持 websockets 的浏览器上,SockJS 也会模拟 websockets 吗?

node.js - Socket.io消息的发送者无法像其他用户一样获取消息

c++ - 广义参数

c++ - 在 C 和 C++ 中都有效的代码在用每种语言编译时会产生不同的行为吗?

symfony + Ratchet : how to send msg to user from controller

使用 Spring Security 和 Keycloak 进行 Spring Websockets 身份验证

php - Thruway PubSub 是否允许在发布前修改消息?

c++ - COLLADA:反向绑定(bind)姿势在错误的空间?

c++ - 为什么 DWORD 值通常以十六进制表示?