我正在读取TCP套接字上的输入行,类似于:
class Bla
def getcmd
@sock.gets unless @sock.closed?
end
def start
srv = TCPServer.new(5000)
@sock = srv.accept
while ! @sock.closed?
ans = getcmd
end
end
end
如果端点在getline()运行时终止连接,则gets()挂起。
我该如何解决这个问题?是否有必要进行非阻塞或定时I / O?
答案 0 :(得分:7)
您可以使用select查看是否可以安全地从套接字获取,请参阅以下使用此技术实现TCPServer。
require 'socket'
host, port = 'localhost', 7000
TCPServer.open(host, port) do |server|
while client = server.accept
readfds = true
got = nil
begin
readfds, writefds, exceptfds = select([client], nil, nil, 0.1)
p :r => readfds, :w => writefds, :e => exceptfds
if readfds
got = client.gets
p got
end
end while got
end
end
这是一个试图打破服务器的客户端:
require 'socket'
host, port = 'localhost', 7000
TCPSocket.open(host, port) do |socket|
socket.puts "Hey there"
socket.write 'he'
socket.flush
socket.close
end
答案 1 :(得分:2)
IO#关闭了吗?当读取器和写入器都关闭时返回true。 在你的情况下,@ sock.gets返回nil,然后再次调用getcmd,这将在一个永无止境的循环中运行。您可以使用select,也可以在获取返回nil时关闭套接字。
答案 2 :(得分:0)
我建议使用readpartial从套接字读取并捕获对等重置:
while true
sockets_ready = select(@sockets, nil, nil, nil)
if sockets_ready != nil
sockets_ready[0].each do |socket|
begin
if (socket == @server_socket)
# puts "Connection accepted!"
@sockets << @server_socket.accept
else
# Received something on a client socket
if socket.eof?
# puts "Disconnect!"
socket.close
@sockets.delete(socket)
else
data = ""
recv_length = 256
while (tmp = socket.readpartial(recv_length))
data += tmp
break if (!socket.ready?)
end
listen socket, data
end
end
rescue Exception => exception
case exception
when Errno::ECONNRESET,Errno::ECONNABORTED,Errno::ETIMEDOUT
# puts "Socket: #{exception.class}"
@sockets.delete(socket)
else
raise exception
end
end
end
end
end
这段代码大量借用了M. Tim Jones的一些nice IBM code。请注意,@ server_socket由以下内容初始化:
@server_socket = TCPServer.open(port)
@sockets只是一个套接字数组。
答案 3 :(得分:0)
我只是pgrep“ruby”找到pid,然后杀掉-9 pid并重启。
答案 4 :(得分:-2)