无法使套接字接受非阻塞红宝石2.2
我整天都在寻找套接字接受非阻塞.我发现recv不受阻碍,但无论如何也无济于事.我的脚本首先启动一个新的套接字类.它使用ip 127.0.0.1和端口6112绑定到客户端.然后启动多线程.多线程需要@ sock.accept. <<那是封锁.然后,我使用了accept_nonblock.但是,这将引发以下错误:
I have been searching the whole day for socket accept non blocking. I found recv non blocking but that wouldn't benefit me in anyway. My script first starts a new socket class. It binds to the client with ip 127.0.0.1 and port 6112. Then it starts multi threading. Multi threading takes @sock.accept. << That is blocking. I have then used accept_nonblock. Though, that would throw me the following error:
IO::EWOULDBLOCKWaitReadable : A non-blocking socket operation could not be completed immediately. - accept(2) would block
我正在使用Ruby 2.2. 注意:我无意使用Rails解决我的问题,也没有给我捷径.我坚持使用纯Ruby 2.2. 这是我的脚本:
I am using Ruby 2.2. NOTE: I do not intend to use Rails to solve my problem, or give me a shortcut. I am sticking with pure Ruby 2.2. Here is my script:
require 'socket'
include Socket::Constants
@sock = Socket.new(AF_INET, SOCK_STREAM, 0)
@sockaddr = Socket.sockaddr_in(6112, '127.0.0.1')
@sock.bind(@sockaddr)
@sock.listen(5)
Thread.new(@sock.accept_nonblock) do |connection|
@client = Client.new(ip, connection, self)
@clients.push(@client)
begin
while connection
packet = connection.recv(55555)
if packet == nil
DeleteClient(connection)
else
@toput = "[RECV]: #{packet}"
puts @toput
end
end
rescue Exception => e
if e.class != IOError
line1 = e.backtrace[0].split(".rb").last
line = line1.split(":")[1]
@Log.Error(e, e.class, e.backtrace[0].split(".rb").first + ".rb",line)
puts "#{ e } (#{ e.class })"
end
end
def DeleteClient(connection)
@clients.delete(@client)
connection.close
end
http://docs.ruby-lang.org/en/2.2.0/Socket.html#method-i-accept_nonblock
accept_nonblock
无法立即接受连接时会引发异常.您应该先挽救此异常,然后再IO.select
套接字.
accept_nonblock
raises an exception when it can't immediately accept a connection. You are expected to rescue this exception and then IO.select
the socket.
begin # emulate blocking accept
client_socket, client_addrinfo = socket.accept_nonblock
rescue IO::WaitReadable, Errno::EINTR
IO.select([socket])
retry
end
补丁已最近被接受,这将为accept_nonblock
,这将使您可以使用它而无需在流控制中使用异常.不过,我还不知道它已经发货.
A patch has recently been accepted which will add an exception: false
option to accept_nonblock
, which will allow you to use it without using exceptions for flow control. I don't know that it's shipped yet, though.