gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 12:03:46 26 4
gpt4 key购买 nike

对于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')

据我了解,如果套接字上没有数据,则 connection.read中的 server.rb应该会阻塞。但是,当我在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:
...

似乎 IO.select认为套接字上有可读取的数据,而没有发送任何此类数据。

在Ruby中使用套接字时,如何实现阻塞读取?我在俯视什么吗?

马特的回答为我指明了正确的方向。对于将来的读者,这是我的新代码。
# server.rb
require 'socket'

class Server
BYTESIZE_OF_PACKED_INTEGER = [1].pack('i').bytesize

def initialize(port)
@port = port
end

def run
Socket.tcp_server_loop(@port) do |connection|
Thread.new do
while packed_msg_bytesize = connection.read(BYTESIZE_OF_PACKED_INTEGER)
msg_bytesize = packed_msg_bytesize.unpack('i').first
msg = connection.read(msg_bytesize)
puts msg
end
end
end
end
end

server = Server.new(16451)
server.run

和客户端代码。
# 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)

最佳答案

如果没有数据,则read将阻止,但在EOF处不会阻止。 IO#read docs say:

When this method is called at end of file, it returns nil or "", depending on length: read, read(nil), and read(0) return "", read(positive_integer) returns nil.



由于在EOF上调用 read不会被阻止,因此 select将立即返回可读的IO。

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

关于ruby - Socket.read()在Ruby中不会阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47241432/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com