Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Socket.read()在Ruby中不会阻塞_Ruby_Sockets - Fatal编程技术网

Socket.read()在Ruby中不会阻塞

Socket.read()在Ruby中不会阻塞,ruby,sockets,Ruby,Sockets,我在Ruby中为一个简单的TCP服务器编写了以下代码: # server.rb require 'socket' class Server def initialize(port) @port = port end def run Socket.tcp_server_loop(@port) do |connection| Thread.new do loop do puts "IO: #{IO.select([con

我在Ruby中为一个简单的TCP服务器编写了以下代码:

# server.rb
require 'socket'

class Server
  def initialize(port)
    @port = port
  end

  def run
    Socket.tcp_server_loop(@port) do |connection|
      Thread.new do
        loop do
          puts "IO: #{IO.select([connection]).inspect} - data: #{connection.read}"
        end
      end
    end
  end
end

server = Server.new(16451)
server.run
以及这个微不足道的TCP客户端代码:

# client.rb
require 'socket'

client = TCPSocket.new('localhost', 16451)
client.write('stuff')
我的理解是,如果套接字上没有数据,那么server.rb中的connection.read应该阻塞。但是,当我在macbook OS X 10.12.5上运行此程序时,它会不断输出以下输出:

IO: [[#<Socket:fd 12>], [], []] - data: stuff
IO: [[#<Socket:fd 12>], [], []] - data: 
IO: [[#<Socket:fd 12>], [], []] - data: 
IO: [[#<Socket:fd 12>], [], []] - data: 
IO: [[#<Socket:fd 12>], [], []] - data: 
IO: [[#<Socket:fd 12>], [], []] - data: 
IO: [[#<Socket:fd 12>], [], []] - data: 
IO: [[#<Socket:fd 12>], [], []] - data: 
...
和客户端代码

# client.rb
require 'socket'

msg = 'stuff'
msg_bytesize = msg.bytesize
packed_msg_bytesize = [msg_bytesize].pack('i')

client = TCPSocket.new('localhost', 16451)
client.write(packed_msg_bytesize)
client.write(msg)
如果没有数据,读取将被阻止,但在EOF时不会。委员会:

当在文件末尾调用此方法时,它返回nil,或者根据长度:read、readnil和read0 return,readpositive\u integer返回nil

由于在EOF上调用read不会阻塞,select将立即返回可读的IO


在您的代码中,第一次读取调用将被阻塞,直到从连接读取所有数据,即另一端已关闭连接。从那时起,它将处于EOF,因此select将以就绪状态返回,read将立即返回一个空字符串。

您知道有没有办法让它在EOF时阻塞?我正在尝试实现一个简单的聊天服务器&客户端,我希望在客户端和服务器之间有一个长期的连接。我最不希望的是,服务器进入100%cpu,只是在大多数时间都没有数据的套接字上主动循环。您可能希望检测并删除这些连接,因此不希望跳过它们。注意:没有可用数据的套接字仍然连接到另一端,而EOF处的套接字断开连接,您只需将其关闭,两者之间存在差异。
# client.rb
require 'socket'

msg = 'stuff'
msg_bytesize = msg.bytesize
packed_msg_bytesize = [msg_bytesize].pack('i')

client = TCPSocket.new('localhost', 16451)
client.write(packed_msg_bytesize)
client.write(msg)