【发布时间】:2015-03-20 10:11:33
【问题描述】:
我正在研究 Tcl 套接字通信,实际上我正在评估 java 客户端发送到 tcl 服务器的命令。在每个客户的新请求中,我正在创建新的interp 并在连接关闭时将其删除。
到目前为止,Java 代码没有问题。
proc writeJavaUTF {stream string} {
set data [encoding convertto utf-8 $string]
if {[string length $data] > 0xffff} {
error "string to long after encoding"
}
set len [binary format S [string length $data]]
puts -nonewline $stream $len$data
flush $stream
}
proc readJavaUTF {stream} {
binary scan [read $stream 2] S len
if {[info exists len]} {
set data [read $stream [expr {$len & 0xffff}]]
return [encoding convertfrom utf-8 $data]
} else {
return "NULL"
}
}
set svcPort 9999
proc svcHandler {sock} {
global tclEngine
puts "receiving socket request from $sock"
set userTclCmd [readJavaUTF $sock]; # Reading the user commands over socket
puts "The command received from user : $userTclCmd"
if {[eof $sock]} {
puts "Socket $sock is closing it's connection. Going to delete it's interpreter"
interp delete $tclEngine($sock)
close $sock
} else {
catch {interp eval $tclEngine($sock) $userTclCmd} cmdResponse
puts "My response : $cmdResponse"
writeJavaUTF $sock $cmdResponse; # Writing the response over socket
}
}
proc accept {sock addr port} {
# Once connection is made, then creating a new slave interpreter
# for the client
global tclEngine
set tclEngine($sock) [interp create]
fileevent $sock readable [list svcHandler $sock]
fconfigure $sock -buffering line -blocking 0 -translation binary
puts "Accepted socket connection from $addr on port $port "
}
#Tcl Array Engine to hold reference of all the client Tcl interpreters
array set tclEngine {}
# Listening for client requests
socket -server accept $svcPort
puts "I am waiting ..."
vwait events
使用readJavaUTF,我从我身边添加了一张支票。
if {[info exists len]} {
}
问题 1:
当从客户端关闭连接时,通过client.close() 也正在调用readJavaUTF。为什么呢 ?早些时候,我已经根据您的(即 Mr.Donal 的代码)answer 明确使用了该版本。
但是,我收到以下错误
can't read "len": no such variable
while executing
"expr {$len & 0xffff}"
(procedure "readJavaUTF" line 4)
invoked from within
"readJavaUTF $sock"
(procedure "svcHandler" line 4)
invoked from within
"svcHandler sock280"
为了处理这个问题,我刚刚添加了那段代码。
问题 2: 如何与从属的主解释器交互,反之亦然。说,我必须从主人的全局空间访问一个变量。那可能吗 ?在此之前,无论我现在采用的方法是一种好方法吗?还有其他建议或改进吗?
【问题讨论】:
-
除了在
catch周围不使用大括号,就像在if {[catch {…} result]} {中一样?对我来说没有什么明显的。 -
对不起。错字。现已更正。想知道我是否在客户端-服务器通信中犯了错误。顺便说一句,我仅从stackoverflow.com/a/16408527/974155 遵循您的常规方法。将很快用正确的代码更新帖子。给我1小时。我正在旅行。
-
@DonalFellows :我设法解决了
catch问题。这是工作。我已经更新了我的问题。还有一些其他问题。
标签: sockets tcl interpreter