Socket.read()在Ruby中不会阻塞
我在Ruby中为一个简单的TCP服务器编写了以下代码: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
# 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)