如何在tcl中打开不是文件名的频道?我已经阅读了文档,但我不是程序员所以我不能理解open和chan命令,因为当我尝试打开一个新的自定义频道时
open customchannel1 RDWR
我收到错误,例如
无法执行“customchannel1”:没有此类文件或目录
而且我完全清楚我没有正确地做到这一点:
chan create read customchannel1
无效的命令名称“customchannel1”...和...无效的命令名称“initialize”
我想要的是两个tcl脚本,可以互相交流。我以为我可以使用频道来做到这一点。
但是,我已成功创建了我想要的套接字测试版本:
proc accept {chan addr port} {
puts "$addr:$port says [gets $chan]"
puts $chan goodbye
close $chan
}
puts -nonewline "master or slave? "
flush stdout
set name [gets stdin]
if {$name eq "master"} {
puts -nonewline "Whats the port? "
flush stdout
set port [gets stdin]
socket -server accept $port
vwait forever
} else {
puts "slave then."
puts -nonewline "Whats the id? "
flush stdout
set myid [gets stdin]
set chan [socket 127.0.0.1 $myid]
puts $chan hello
flush $chan
puts "127.0.0.1:$myid says [gets $chan]"
close $chan
}
在上面的示例中,我可以运行程序的3个实例:具有不同端口号的2个“主服务器”,以及可以根据它选择的端口/“id”与任何一个进行通信的“从服务器”。
如果我知道如何使用open命令而不是socket命令打开一个通道,我可以在不使用套接字的情况下实现上述代码,或者使用jimmy-rigging将端口用作uniq id,但我能找到的每个示例都打开文件和写入文件或标准输出,您不必首先创建。
感谢您帮助我理解这些概念以及如何更好地实施这些概念!
答案 0 :(得分:2)
频道只是处理已经打开的文件或套接字的高级方法。
从手册页:
此命令提供了几个操作,用于读取,写入和操作开放通道(例如使用open和socket命令创建的,或者默认命名通道stdin,stdout或stderr,它们对应于进程的标准输入,输出和错误流分别)。
所以你用套接字做的事情是正确的。您可以使用chan
命令配置打开的套接字。
答案 1 :(得分:1)
将两个脚本连接在一起时,您可能会考虑使用管道。例如,您可以将一个脚本作为另一个脚本的下级进程运行。主人这样做:
set pipe [open |[list [info nameofexecutable] $thescriptfile] "r+"]
获取双向(因为r+
)管道与孩子交谈,这可以反过来正常使用stdout和stdin。
在一个过程中,chan pipe
可用,它返回一对通过OS匿名管道连接的通道。
使用这些功能时,如果您记得使用fconfigure
将-buffering
转为none
,这确实很有帮助。否则你可能会遇到死锁,而输出管道就位于某个地方的缓冲区中,这是你不想要的。最终的答案是使用Expect,它使用Unix ptys而不是管道,但如果你记得调整缓冲,你可以非常高效。