2016-02-13 66 views
0

我在Ruby中使用Unix Domain Socket編寫簡單的echo服務器/客戶端。這裏是我的代碼:如何在Ruby中檢測斷開的Unix域套接字?

server.rb

require 'socket' 

# Listens server.sock and enters an infinite loop 
Socket.unix_server_loop('server.sock') do |sock, addr| 
    # When accepted a connection, creates a new thread 
    puts "Accepted connection from:" 
    Thread.new do 
    loop do 
     rs = IO.select([sock], [], [sock]) 
     p rs 
     input = sock.gets.chomp 
     puts "input = [#{input}]" 
     sock.puts("response to #{input}") 
    end 
    puts "Thread quits." 
    sock.close 
    end 
end 

puts "Server quits." 

client.rb

require 'socket' 

UNIXSocket.open('server.sock') do |sock| 
    5.times do |i| 
    begin 
     sock.puts "#{Time.now}: Hello #{i} from #{Process.pid}" 
     puts "Recived " + sock.gets 
     sleep 1 
    rescue Errno::EPIPE => e 
     puts "Connection closed." 
     break 
    end 
    end 
    sock.close 
end 

puts "Client quits." 

他們除了服務器不能檢測客戶端在quiting做工精細,它永遠等待輸入。雖然select返回文件描述符(這意味着描述符已準備好讀取,但據我所知),sock.gets塊。如何檢測斷開連接的套接字並使服務器線程正確退出?

回答

0

當連接關閉時,返回sock.gets零即

input = sock.gets 
break if input.nil? 
input = input.chomp 

應該工作。

爲了調試

require 'socket' 
Thread.abort_on_exception=true 

都可以使用。然後原始代碼將結束,因爲的

未定義的方法`格格」的零:NilClass(NoMethodError)

有關更多細節,請參見this answer

+0

啊,我試着檢查空字符串,但沒有拿出零。它的工作,謝謝。但是,那麼,爲什麼我的代碼不會引發NoMethodError,雖然調用nil.chomp? – aosho235

+0

@ aosho235我的猜測是'NoMethodError'被引發,但它被丟棄了,因爲它發生在一個線程中。 –

+0

再次感謝@ J.J。 Hakala。通過使用'Thread.abort_on_exception = true',Ruby打印了異常。 – aosho235