无法理解通过 Web 套接字进行 XOR 数据帧的二进制扫描结果?

问题描述 投票:0回答:1

我可能会做一些非常愚蠢的事情,而且我在理解这些结果是如何产生的方面遇到了很大的困难。

通过从浏览器到本地 Tcl 脚本的 Web 套接字,将传递以下 JSON 字符串。

{"ops":"AudioNotes EditSgmtTitle","params":{"doc_id":100,"title":"Short Segment Title (Looks Pretty Good aa Maybe)"},"reqId":1}
。我添加了从 UI 编辑段标题的功能,并通过意外输入一些垃圾字母来查看数据库是否正在更新,从而找到导致读取端出现问题的字符串长度。

如果将此字符串粘贴到 Kate 文本编辑器中,它的长度似乎为

127
。如果将其置于活动的 tclsh 会话中,则
[string length ...]
127

XOR 帧在 Tcl 中读取,开头为:

if { [binary scan [coread $sock 2] B16 bits] != 1
  || [scan $bits %1b%1b%1b%1b%4b%1b%7b \
        fin rsv1 rsv2 rsv3 op m pl] != 7 } {

它返回

pl
,表示有效负载长度为
126
。结果是,当接下来的两个字节被读取为无符号整数时,它返回一个不同大小的非常大的值。我正在使用
[binary scan [coread $sock 2] Su pl]

title
属性中有一个
aa
。如果将其更改为单个
a
,则
pl
仍然是
126
并且一切正常,也就是说,XOR 帧被无错误地读取、解码,并将正确的
title
写入到
doc_id 的数据库中
100

我的问题是,如何将两个字符串读取为长度 126 以及如何纠正这个问题? (我忘记了 126 只是告诉我们读取接下来的 16 位来获取长度,在这些示例中这些应该是 126 和 127。)

也奇怪的是,有一次错误是:

Error in XOR_Read: expected non-negative integer but got "6717638123588400952" Closing socket.

另一次:

Error in XOR_Read: expected non-negative integer but got "18173768903968447991" Closing socket.

在两个实例中发送相同的字符串(带有

aa
),但在读取
$pl
为 126 的接下来两个字节时获得不同的值。我将请求写入浏览器中的 console.log 和字符串在所有情况下都是相同的。

我意识到奇怪的窃听项目可能需要一段时间才能显现出来,但我已经使用套接字和 XOR 解码代码大约两年了,没有出现任何问题。

感谢您考虑我的不寻常问题。

这些是指向这些位应该是什么的文档的链接。

WebSocket 协议MDN

也许我在 coread 协程中做错了什么,因为长度必须恰好为 127 才会失败; 126 和 128 以及我尝试过的所有其他尺寸都可以。以前肯定从来没有精确到过 127。

proc ::WEBS::coread {sock reqBytes} {
  set fullRead {}
  set remBytes $reqBytes
  while {![chan eof $sock]} {
    yield
    append fullRead [set loopRead [read $sock $remBytes]]
    if {[incr remBytes -[string length $loopRead]] == 0} {
      return $fullRead
    }
  }
  throw {COREAD EOF} "Unexpected WEBS EOF"
}
websocket tcl xor
1个回答
0
投票

您没有显示实际处理长度处理的代码,所以我只能猜测。在 websocket 中,长度在 7 位字段中指定。长度值 126 和 127 有特殊含义。如果长度字段为 126,则实际长度在接下来的 2 个字节中指定。如果长度字段为 127,则实际长度在接下来的 8 个字节中指定。也许你的代码正在做类似的事情来处理这个问题:

if {$pl == 126} {
    binary scan [coread $sock 2] Su pl
}
if {$pl == 127} {
    binary scan [coread $sock 8] Wu pl
}

仅当有效负载长度为 127 时才会失败,因为这两个条件都成立。第一个

pl
是 126,导致代码从接下来的 2 个字节读取长度,使得
pl
为 127。如果 original
pl
值为 127,则应该从接下来的 8 个字节中获取长度。但你不能两者都做。

如果是这种情况,解决方案很简单:将第二个检查放在

else
块中:

if {$pl == 126} {
    binary scan [coread $sock 2] Su pl
} elseif {$pl == 127} {
    binary scan [coread $sock 8] Wu pl
}

以相反的方式进行检查也将起作用,假设浏览器中正确实现了 websockets(即:它不会发送 8 个字节的 126 长度)。

© www.soinside.com 2019 - 2024. All rights reserved.