【问题标题】:TCL raw socket multiline responseTCL 原始套接字多行响应
【发布时间】:2021-05-25 08:08:33
【问题描述】:

我正在使用 TCL 作为语言的环境中编写测试代码。通过 raw socked 向设备发送命令后,我收到响应,有时是多行(设备终端不是很稳定)。

下面的代码只显示了一行。如果响应确实不止一行,如何轻松更改为返回多行?

set connection [socket $session_ip $session_port]
puts $connection "my_command_here"
flush $connection
puts [gets $connection]

作为一种解决方法,我重复了最后两个步骤

    flush $connection
    puts [gets $connection]

不幸的是,如果只有一条线路响应,它就会冻结。尝试使用 read 而不是 gets 但没有正确的结果。

【问题讨论】:

  • 定义“没有正确的结果”。对等端是否发送行?
  • 它冻结而没有响应。
  • 怎么知道对方发了多行回复?您是否有一些代码可以查看一行并说“这条线的末端被切断了”? (我问是因为该代码将使编写用于读取输入和重建原始行的异步处理程序非常更容易编写。)
  • 我知道通过在设备上进行手动操作 - 已经多次观察到这种行为(响应一条或多条线)。

标签: sockets tcl response multiline


【解决方案1】:

如果没有确定的协议来确定响应中有多少行,则必须使用非阻塞输入。还建议使用基于事件的处理:

set connection [socket $session_ip $session_port]
# Set the connection to non-blocking and line buffering
fconfigure $connection -blocking 0 -buffering line
# Set up a proc to react to incoming events on the socket
# These can be: Receiving data and the connection being closed
fileevent $connection readable [list eventhandler $connection]

proc eventhandler {fd} {
    if {[eof $fd]} {
        puts "Remote side closed the connection"
        close $fd
    } elseif {[gets $fd line] != -1} {
        puts $line
    }
}

puts $connection "my_command_here"

vwait forever

使用基于事件的编程需要一种非常不同的程序结构方式。这个主题太广泛了,无法在这里讨论。如果您不熟悉该概念,请在网络上查找更多信息。

【讨论】:

  • 如果你有 8.6 或更高版本,使用协程可以使编写异步处理程序更容易正确。
  • 感谢您的回答。我可以假设响应线的范围可以在 1 到 5 之间。在这种情况下,最简单的解决方案是什么?
  • 这没有任何区别。如果它不是一个可以预先确定的数字,您将需要处理不确定性。
猜你喜欢
  • 2016-07-10
  • 1970-01-01
  • 2018-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-09-22
  • 1970-01-01
  • 2020-02-29
  • 2017-10-28
相关资源
最近更新 更多