【问题标题】:Decoding Binary Data in Tcl在 Tcl 中解码二进制数据
【发布时间】:2020-08-20 13:04:56
【问题描述】:

我正在使用套接字从 TCL 中的 TCP 端口读取数据。消息不以任何换行符结尾,但它们包含一个包含数据字节数的标头。

我有以下代码从套接字(16bit little endian)读取两个字节的数据并将其转换为一个整数,然后我可以在循环中使用它来读取其余数据:

  binary scan [read $Socket 2] s* length

在这种情况下,$Socket 是我的套接字,它已被配置为使用二进制编码。

这很好用,除非高字节或低字节是 0x0D。看来 TCL 将 0x0D 和 0x0A 都读取为“\n”,然后默认为 0x0A,因此代码确实可以正常工作。例如 13 读作 10。如何阻止这种情况发生?

【问题讨论】:

    标签: tcp binary tcl


    【解决方案1】:

    如果要在其中移动二进制数据,则应将套接字置于二进制模式。

    chan configure $Socket -translation binary
    # Use [fconfigure] instead of [chan configure] in older Tcl versions
    

    这会禁用 Tcl 通常执行的所有自动处理——你的描述说你遇到了行尾转换问题——并使得read 将只传递一个字节字符串(正式地U+000000 和 U+0000FF 之间的字符串,内部使用高效的内存编码方案)。

    对于文件,您可以在打开时将b 包含在控制模式中以完成此操作。对于套接字,您需要自己执行此操作。

    【讨论】:

    • 如果消息的其余部分是字符串,则可能需要进一步解码;在这种情况下使用encoding convertfrom 是很正常的。
    • 谢谢 - 我在 Tcl 8.3 中使用:fconfigure $Socket -translation binary
    • 8.3? 1990 年代不受支持的 Tcl 版本,蝙蝠侠!
    • 是的,我正在更新一些非常古老的代码! chan configurefconfigure之间只有语法区别吗?
    【解决方案2】:

    除了配置二进制编码,还需要设置翻译为'lf'。由于这是一种经常发生的情况,因此可以使用一种简写方式来进行这两种设置:

    fconfigure $Socket -translation binary
    

    【讨论】:

      猜你喜欢
      • 2014-08-09
      • 1970-01-01
      • 2021-12-05
      • 2011-11-02
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      • 2017-07-14
      相关资源
      最近更新 更多