Tcl 一段时间后套接字超时

Tcl 一段时间后套接字超时,tcl,Tcl,如果服务器进入无限循环,我们如何在一段时间后关闭服务器连接 以下是我正在尝试的代码: set s [socket $host $port] fconfigure $s -blocking 1 -buffering line after 2000 set end 1 vwait end if { $s != "" } { puts -nonewline $s "$msg\n.\n" flush $s

如果服务器进入无限循环,我们如何在一段时间后关闭服务器连接

以下是我正在尝试的代码:

    set s [socket $host $port]
    fconfigure $s -blocking 1 -buffering line
    after 2000 set end 1
    vwait end
    if { $s != "" } {

            puts -nonewline $s "$msg\n.\n"
            flush $s
            fileevent $s readable [set answer [read $s]]

            puts "$answer"

            if {[catch {close $s}]} {
                    puts "Server hanged"
            }

如果服务器给出的答案没有任何问题,则上述代码有效。如果服务器进入无限循环,它将继续挂起在
read$s
中。请帮助了解如何在非阻塞模式下处理此
读取套接字
,就像在
fconfigure

中一样。如果使用阻塞套接字,您将遇到以下问题:将通道置于非阻塞模式是解决方法(以及在
之后使用
写入超时)。这确实意味着您必须处理异步编程的所有复杂性,但这是您需要在这里进行的权衡

可以挂起东西的两个地方是连接建立和数据生成。因此,您将使用异步连接和非阻塞检索

set s [socket -async $host $port]
fconfigure $s -blocking 0

fileevent $s writeable [list connected $s]
proc connected {s} {
    global msg
    fileevent $s writeable {}
    puts -nonewline $s "$msg\n.\n"
    flush $s
    fileevent $s readable [list accumulateBytes $s]
}

set accumulate ""
proc accumulateBytes {s} {
    global accumulate end
    append accumulate [read $s]
    if {[eof $s]} {
        set end 0
    }
}

# Longer *total* time to connect and communicate.
after 5000 set end 1
vwait end

catch {close $s}

if {$end} {puts "timed out"}
puts "received message: $accumulate"

我现在没有答案,但请注意,调用
fileevent
的方式不会将
[设置答案[read$s]]]
安装为回调脚本。相反,它会在调用过程中执行该操作(尝试从套接字读取并将结果分配给
answer
),并将从套接字读取的内容设置为回调脚本,这不太可能是您想要的。延长超时时间