我正在尝试创建一个 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=