在 Tcl 中解码二进制数据
Decoding Binary Data in Tcl
我正在使用套接字从 TCL 中的 TCP 端口读取数据。消息不以任何换行符结尾,但它们包含一个 header 包含数据字节数的容器。
我有以下代码从套接字(16 位小端)读取两个字节的数据并将其转换为一个整数,然后我可以在循环中使用它来读取其余数据:
binary scan [read $Socket 2] s* length
在这种情况下,$Socket 是我的套接字,它已配置为使用二进制编码。
除了高位字节或低位字节为 0x0D 的情况外,此方法运行良好。 TCL 似乎将 0x0D 和 0x0A 都读取为“\n”,然后默认为 0x0A,因此代码可以正常工作。例如 13 读作 10。如何阻止这种情况发生?
如果要在套接字上移动二进制数据,则应将套接字置于二进制模式。
chan configure $Socket -translation binary
# Use [fconfigure] instead of [chan configure] in older Tcl versions
这会禁用 Tcl 通常执行的所有自动处理 — 您的描述说您遇到了 end-of-line 转换的问题 — 并使 read
只提供一个字符串字节(形式上是 U+000000 和 U+0000FF 之间的字符串,内部使用高效的 in-memory 编码方案)。
对于文件,您可以在打开时在控制模式中包含 b
来为您完成此操作。对于套接字,你需要自己做。
除了配置二进制编码,还需要设置翻译为'lf'。由于这种情况经常发生,因此有一个 shorthand 用于进行这两个设置:
fconfigure $Socket -translation binary
我正在使用套接字从 TCL 中的 TCP 端口读取数据。消息不以任何换行符结尾,但它们包含一个 header 包含数据字节数的容器。
我有以下代码从套接字(16 位小端)读取两个字节的数据并将其转换为一个整数,然后我可以在循环中使用它来读取其余数据:
binary scan [read $Socket 2] s* length
在这种情况下,$Socket 是我的套接字,它已配置为使用二进制编码。
除了高位字节或低位字节为 0x0D 的情况外,此方法运行良好。 TCL 似乎将 0x0D 和 0x0A 都读取为“\n”,然后默认为 0x0A,因此代码可以正常工作。例如 13 读作 10。如何阻止这种情况发生?
如果要在套接字上移动二进制数据,则应将套接字置于二进制模式。
chan configure $Socket -translation binary
# Use [fconfigure] instead of [chan configure] in older Tcl versions
这会禁用 Tcl 通常执行的所有自动处理 — 您的描述说您遇到了 end-of-line 转换的问题 — 并使 read
只提供一个字符串字节(形式上是 U+000000 和 U+0000FF 之间的字符串,内部使用高效的 in-memory 编码方案)。
对于文件,您可以在打开时在控制模式中包含 b
来为您完成此操作。对于套接字,你需要自己做。
除了配置二进制编码,还需要设置翻译为'lf'。由于这种情况经常发生,因此有一个 shorthand 用于进行这两个设置:
fconfigure $Socket -translation binary