一段时间后套接字超时

时间:2014-06-19 15:41:04

标签: 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
            fileevent $s readable [set answer [read $s]]

            puts "$answer"

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

如果服务器给出的答案没有任何问题,上面的代码就可以了。如果服务器进入无限循环,它将继续挂在read $s中。请帮助您了解如何在非阻止模式下处理此read socket,如fconfigure中所述。

1 个答案:

答案 0 :(得分:2)

如果您正在使用阻塞套接字,则会遇到此问题:将通道置于非阻塞模式是修复(与使用after一起写入超时)。这确实意味着您必须处理异步编程的所有复杂性,但这需要您在此处进行权衡。

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

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"