新协议握手hybi-10中的数据编码

0 投票
1 回答
1066 浏览
提问于 2025-04-17 02:41

我在用Python和JavaScript做WebSocket,之前Google Chrome使用的握手协议是draft hybi-00。我猜Google Chrome最近把协议改成了draft hybi-10

所以今天我更新了握手的代码,现在WebSocket成功创建并打开了。在JavaScript的onopen事件中,我发送了一条简单的文本消息:

viz.ws = new WebSocket("ws://127.0.0.1:5500");
            
viz.ws.onopen = function() {
    viz.ws.send("TEST\n");
};

我的Python服务器收到了这些数据。不过,这些数据好像被编码了,我无法得到我发送的简单文本"TEST\n"

    def recv_data(self, client, count):
    
        try:
            data = client.recv(count)
        
        except:
            return False
        
        print data
        print data.decode('utf-8','ignore')

        return data.decode('utf-8', 'ignore')

打印出来的结果是这样的:

üàÍu┬¯é0æ║▄
u0

而且每次都不一样,但发送的文本总是TEST\n

另外,服务器收到了这些数据,但客户端没有收到从服务器发送过来的任何数据。

我听说hybi-10使用了二进制数据……我是不是在代码中漏掉了什么数据转换?抱歉,我对WebSocket真的很陌生,这些协议搞得我有点晕……

1 个回答

1

在HyBi协议中,数据的格式发生了很大的变化(HyBi-00其实就是Hixie-76)。新的数据格式可以在这个图示中找到。

另外,从客户端发送到服务器的数据是需要进行掩码处理的。掩码是数据帧负载的前4个字节,并且使用一个简单的算法在原地进行解码(实际上也是编码):

data[i] = data[i] XOR mask[j MOD 4]

每个数据帧的掩码密钥都是不同的,这就是为什么即使你发送相同的数据,每次得到的负载也会不同。

如果客户端没有收到你发送的数据,很可能是因为你没有正确地格式化数据。另外要注意,Chrome 14和Firefox 6/7还不支持二进制数据,所以操作码需要设置为1,以表示这是一个文本(UTF-8)帧。

撰写回答