2014-06-19 72 views
2

如果服務器進入無限循環,在某段時間之後如何關閉服務器連接?一段時間後套接字超時

這裏是我正努力代碼:

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一樣。

+2

我現在還沒有答案,但請注意,您調用'fileevent'的方式不會_安裝'[set answer [read $ s]]'作爲回調腳本。相反,它在該調用期間執行該操作(嘗試從套接字中讀取並將結果分配給「answer」),並將從套接字讀取的任何內容設置爲回調腳本,這很可能不是您想要的。 –

+0

Incerease超時期 – xrcwrn

回答

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" 
+0

謝謝Donal ..它完美地滿足了我的要求.. – Tamilan