2
我在Ruby中提出了一個簡單的TCP服務器演示。我的第一個演示是使用經典的C風格的bind-listen-accept-read-write-close方法。此代碼工作得很好,第一次:啓動時基本Ruby TCP服務器演示失敗:`bind':地址已在使用中,Errno :: EADDRINUSE
require 'socket'
class Server
def start(bind: '127.0.0.1', port: nil, backlog: 1)
Socket.new(:INET, :STREAM).tap do |sock|
sock.bind Addrinfo.tcp bind, port
sock.listen backlog
# the codes of client connecting with it here is for reproducing the issue more easily
c = Socket.new(:INET, :STREAM)
c.connect Addrinfo.tcp '127.0.0.1', port
client, client_addr = sock.accept
puts "connected from #{client_addr.ip_address}:#{client_addr.ip_port}"
client.puts "hi"
client.close
sock.close
end
end
end
Server.new.start(port: 23333)
然而,當我試圖再次運行它,我得到的EADDRINUSE
的錯誤:
`some-script.rb:8:in `bind': Address already in use - bind(2) for 127.0.0.1:23333 (Errno::EADDRINUSE)`
約30秒後,我可以成功啓動腳本再次。不知道這是否由內核完成。
Dosn't Socket#close
完全關閉socket和內核關閉TCP連接?
我在Mac OS 10.11.1和Ubuntu 14.04上都試過了,得到了同樣的結果。 閱讀ruby的源代碼(socket.c)後,我仍然無法弄清楚。
有什麼建議嗎?
謝謝@keithmo,重複使用作品。 – qhwa