我正在用C++编写一个WebSocket实现。现在它几乎完成了,我想在这个WebSocket echo服务器上测试它。首先,我在HTTP握手中连接到它和Upgrade
到WebSocket协议。
然后我发送一个文本帧;这是一个测试";作为内容。这是我的程序发送的:
FRRR-OP- M-LENGTH MASK-KEY
10000001 10001110 00000100
MASK-KEY MASK-KEY MASK-KEY
01000101 11010000 01101011
--DATA-- --DATA-- --DATA--
01010000 00101101 10111001
--DATA-- --DATA-- --DATA--
00011000 00100100 00101100
--DATA-- --DATA-- --DATA--
10100011 01001011 01100101
--DATA-- --DATA-- --DATA--
01100101 10000100 00001110
--DATA-- --DATA--
01110111 00110001
我会很快解释这些字母:
- F:表示这是消息中的最后一个片段(引用RFC6455)
- RRR:RSV1、RSV2、RSV3。除非使用扩展名,否则始终为0
- -OP-:操作代码。操作代码1=短信
- M:指示数据是否被屏蔽。1=它被屏蔽
- -LENGTH:数据的字节长度(不包括掩码)
- MASK-KEY:用于加密数据的密钥。总是4字节长
来自RFC6455
要将屏蔽数据转换为未屏蔽数据,或反之亦然应用以下算法。同样的算法也适用无论翻译的方向如何,例如应用步骤来屏蔽数据,如同取消屏蔽数据一样。
变换后的数据的八位位组i("transformed-Octet-i")是XOR原始数据的八位位组i("original-octet-i")掩蔽密钥("masking-key-octet-j")的索引i模4:
j = i MOD 4 transformed-octet-i = original-octet-i XOR masking-key-octet-j
- 数据:加密数据("This is a Test")
发送此帧后,echo服务器需要很长时间才能响应(~45秒),这就是我得到的数据:
FRRR-OP- M-LENGTH --DATA--
10000001 00001110 01010100
--DATA-- --DATA-- --DATA--
01101000 01101001 01110011
--DATA-- --DATA-- --DATA--
00100000 01101001 01110011
--DATA-- --DATA-- --DATA--
00100000 01100001 00100000
--DATA-- --DATA-- --DATA--
01010100 01100101 01110011
--DATA-- --DATA-- --DATA--
01110100 10001001 00000000
将数据转换为字符串会导致这种情况。
This is a Test‰
所以这里出了问题。它不可能是错误的OP代码,因为服务器会做出响应。这不可能是错误的加密,因为服务器可以解密数据。长度也没有错,你可以怎么看。然而,奇怪的是,服务器需要很长时间才能做出响应。它似乎在等待更多的数据。
最后两个字节(10001001
、00000000
)是一个没有有效负载的ping帧。