我可能会做一些非常愚蠢的事情,而且我在理解这些结果是如何产生的方面遇到了很大的困难。
通过从浏览器到本地 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 解码代码大约两年了,没有出现任何问题。
感谢您考虑我的不寻常问题。
这些是指向这些位应该是什么的文档的链接。
也许我在 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 中,长度在 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 长度)。