【问题标题】:Tcl - get message in socket bufferTcl - 在套接字缓冲区中获取消息
【发布时间】:2020-12-24 08:22:05
【问题描述】:

我已经创建了一个套接字客户端来连接到 python 服务器。

我检查了tcl 手动脚本,它说 "gets" - 将队列排到 EOL 字符。

手册:https://www.tcl.tk/man/tcl8.4/TclCmd/gets.htm

但是,从python服务器发送的消息是没有EOL的。

是否可以直接从缓冲区中获取?

【问题讨论】:

    标签: sockets tcl


    【解决方案1】:

    网络连接的行尾标准是 CRLF,Tcl 默认打开套接字,但服务器可能不遵循。

    尝试fconfigure $mysocket -translation auto 接受 CR、LF 和 CRLF。

    【讨论】:

      【解决方案2】:

      在处理二进制数据(即不是基于行)时,read 命令通常比gets 更合适。

      read 命令的手册页可在此处找到:http://www.tcl.tk/man/tcl/TclCmd/read.htm

      我还鼓励您使用比已有十多年历史的 8.4 更新的 Tcl 版本。当前版本是 Tcl 8.6。


      在 cmets 中提供更多详细信息后更新:

      如果服务器没有指明它发送的数据的长度,没有在末尾发送换行符,也没有关闭套接字,这对客户端来说非常困难。

      在 Tcl 中处理该问题的常用方法是将通道设置为非阻塞并侦听可读事件:

      set fd [socket $server $port]
      fconfigure $fd -blocking 0 -buffering line
      fileevent $fd readable [list receive $fd]
      # Send an initial string to the server
      puts $fd Hello!
      
      proc receive {fd} {
          if {[eof $fd]} {
              puts "The server closed the connection"
              close $fd
              exit
          } else {
              set data [read $fd]
              if {$data ne ""} {
                  puts "Received: $data"
                  # Send a response back to the server
                  if {$data eq "Hey guys"} {
                      puts $fd "Hey you"
                  } else {
                      puts $fd "I don't understand $data"
                  }
              }
          }
      }
      
      # Run the event loop (not necessary when using Tk)
      vwait forever
      

      通过使通道不阻塞,read 命令将返回该时间点的所有可用数据。当有任何可用数据时触发可读事件。在连接后立即调用read 可能根本不会产生任何数据。所以这行不通。另一种方法是每 x 毫秒轮询一次,但效率很低。

      注意:有人可能会指出上面的receive proc是不正确的,因为“必须在读取后检查eof”。但是那些人并没有完全掌握基于事件的文件处理。如果read 命令遇到文件或流的结尾,可读事件将立即再次触发。再次调用receive proc,然后处理文件结束条件。

      【讨论】:

      • 我没有发送二进制数据...在 python 端,它发送一些类似connection.sendall('Hello World') 的东西。因此没有 EOL。
      • 对于 Tcl 版本,我正在一个我无法改变很多的环境中工作。那里只提供 tcl 8.4。我也在为此苦苦挣扎。哈哈
      • 我也试过read命令,但是如果numChars超过了消息的长度,tcl还是收不到。在我的情况下,来自 python 的消息的长度是不确定的。可能是 Hello WorldHey guy
      • 我已经更新了我的答案以解决您的 cmets。
      • 我还是没用。更准确地说,我在我的应用程序中修改了它,但我失败了。我想要做什么 tcl send -> python recv -> python 处理消息 -> python send -> tcl recv -> tcl next send 等。因此我不能使用@ 987654337@ 因为我还要发其他消息。
      猜你喜欢
      • 2012-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-29
      • 1970-01-01
      相关资源
      最近更新 更多