Websocket 握手响应未从 TCP 转发到客户端

Websocket 握手响应未从 TCP 转发到客户端

我正在尝试创建一个 websocket 服务器。我可以看到 websocket 客户端的打开握手。客户端笔记本电脑收到了我的响应(我可以在 wireshark 上看到这一点)。因此 TCP 连接已建立。但客户端(chrome websocket 客户端扩展)没有收到握手数据包。TCP 不将握手转发给客户端或客户端无法读取 TCP 消息的可能原因是什么?

客户端握手:

GET HTTP/1.1
Upgrade: websocket
Connection:Upgrade
Cache-Control:no-cache
Host:192.168.0.101
Origin:http://www.websocket.org
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
Sec-WebSocket-Key: qrmw/m+BoZije6h9HYKmVw==
Sec-WebSocket-Version:13
Upgrade:websocket

服务器响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: jj1g5Io57m9ks8cme3jkbyo2asc=
Access-Control-Allow-Origin: http://www.websocket.org
Server: xyz
Sec-WebSocket-Extensions: 

谢谢!

答案1

根据 WebSockets 规范,Sec-WebSocket-Extensions不允许使用空白标头,空白标头会被视为格式错误的数据,并且“收到此类格式错误的数据的接收者必须立即WebSocket 连接失败“(强调他们的)

https://www.rfc-editor.org/rfc/rfc6455#section-9.1

如果您的 WebSockets 服务器不支持任何这些扩展,则应忽略该标头,而不是附加它但使其格式错误(空白)。规范中的其他地方提到,如果服务器的响应中不存在该标头,则客户端应将支持扩展列表视为空。

更新后添加:
我也认为您的服务器的Sec-WebSocket-Accept输出不正确。

我编写了以下 shell 函数来获取一个Sec-WebSocket-Key值并Sec-WebSocket-Accept从中计算出

wscalc () {
    WSGUID="258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
    echo -n "${1}${WSGUID}" | openssl sha1 -binary | openssl base64
}

我使用 WebSockets 规范中的示例进行了测试RFC6455并得到正确的值:

$ wscalc dGhlIHNhbXBsZSBub25jZQ==
s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

但是当我在您的客户端上运行它时Sec-WebSocket-Key,我得到的值与您的服务器在其处放置的值不同Sec-WebSocket-Accept

$ wscalc 'qrmw/m+BoZije6h9HYKmVw=='
B18B9fmlWz7D6Gu9eCWRNkcB1II=

相关内容