ruby中的非阻塞tcp客户端套接字失败

时间:2017-09-14 03:00:19

标签: ruby networking

尝试以非阻塞方式创建TCP套接字,但失败了。有什么想法吗?

$ ruby nonblock_sock.rb 
/home/tom/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/socket.rb:1207:in `__connect_nonblock': Operation now in progress - connect(2) would block (IO::EINPROGRESSWaitWritable)
    from /home/tom/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/socket.rb:1207:in `connect_nonblock'
    from nonblock_sock.rb:6:in `<main>'

以下是代码段

#not working yet, 
require 'socket'

socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0) 
sockaddr = Socket.pack_sockaddr_in(80, 'localhost') 
socket.connect_nonblock(sockaddr);

1 个答案:

答案 0 :(得分:2)

将其更改为:

require 'socket'
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0) 
sockaddr = Socket.pack_sockaddr_in(80, '127.0.0.1')  #this
socket.connect_nonblock(sockaddr)

如果我没记错的话,需要在creating address时传递IP而不是主机名(localhost)。 有了这个,connect_nonblock应该在后台以非阻塞方式连接EINPROGRESS,我认为我们可以在以后查看IO.select

修改IO::EINPROGRESSWaitWritable按预期提出。 connect_nonblock为后台留下连接建立过程并将其提升。

你应该像这样处理它:

begin
  socket.connect_nonblock(sockaddr)
rescue Errno::EINPROGRESS 
  IO.select(nil, [socket]) #wait for socket to be writable
  begin
    socket.connect_nonblock(sockaddr)
  rescue Errno::EISCONN
    #=> This means connection to remote host has established successfully.
    socket.write("stuff")
  end
end