Ruby、Telnet、无超时读取多行响应

Ruby、Telnet、无超时读取多行响应,ruby,json,telnet,Ruby,Json,Telnet,我需要一些提示/帮助,如何将多行响应读入变量。 我当前的命令会产生多行响应,但之后会超时 以下是如何设置我的连接: connection = Net::Telnet.new('Host' => host,'Port' => 4800, 'Telnetmode' => false, 'Timeout' => 1) 以下是我的请求以及如何保存它: puts "Weather request\n" connection.cmd("{weather}"){ |c| print

我需要一些提示/帮助,如何将多行响应读入变量。 我当前的命令会产生多行响应,但之后会超时

以下是如何设置我的连接:

connection = Net::Telnet.new('Host' => host,'Port' => 4800, 'Telnetmode' => false, 'Timeout' => 1)
以下是我的请求以及如何保存它:

puts "Weather request\n"
connection.cmd("{weather}"){ |c| print c }
parsed = JSON.parse(str)
puts "#{parsed}\n\n"
下面是错误:

/usr/lib/ruby/1.9.1/net/telnet.rb:558:in `waitfor': timed out while waiting for more data (Timeout::Error)
    from /usr/lib/ruby/1.9.1/net/telnet.rb:695:in `cmd'
    from ruby_check.rb:37:in `<main>'

您正在将超时设置为1秒,并且没有指定什么是
str
。您可以尝试增加超时值,甚至将其设置为。相信这是来自
.cmd
的结果,请尝试以下操作:

connection = Net::Telnet.new(
  "Host" => host, "Port" => 4800, 
  "Telnetmode" => false, "Timeout" => false)

puts "Weather request...\n"

str = connection.cmd("{weather}"){ |c| print c }
parsed = JSON.parse(str)

puts "#{parsed}\n\n"
为什么要暂停? 报告说:

对于某些协议,在创建Telnet对象并使用cmd()调用时,可以指定一次提示选项;对于其他调用,您必须指定要查找的响应序列作为每个cmd()调用或直接调用put()和waitfor()的匹配选项;对于其他人,您必须使用sysread()而不是waitfor(),并自己解析服务器响应

当与表示方法:

向主机发送字符串,并读取所有接收到的数据,直到看到提示或其他匹配序列

您没有指定自定义的
提示符
匹配
选项,因此
#cmd
正在等待服务器发送与默认的
Net::Telnet
提示符(
/[$%\z/n
)匹配的内容,以指示消息的结束。 如果消息没有以这种提示结束,那么它将永远等待

可能的解决方案 匹配服务器的提示 如果服务器确实发送某种类型的提示以指示其已完成发送数据,并且您应该键入下一个命令,则可以将与之匹配的正则表达式传递给
Net::Telnet
初始化器。例如,如果服务器提示您使用
命令:
,您可以使用:

connection = Net::Telnet.new(
  "Prompt" => /command: \z/,
  # …
)
匹配响应的结尾 如果没有提示,但等待的响应以特定字符序列结束,则可以在调用
#cmd
时显式指定
Match
选项。例如,如果您的响应是单个JSON数组,那么它将以
]
结尾,因此您可以使用以下方法:

connection.cmd("String" => "{weather}", "Match" => "]") { |c| print c }
放弃
Net::Telnet
并使用
TCPSocket
如果没有提示,也没有已知的结尾,您可以尝试使用
Net::Telnet
对象的底层来读取数据,而不使用
#cmd

connection.puts("{weather}")
connection.sock.readline

此时,在普通的
TCPSocket

上使用
Net::Telnet
可能没有多大好处。您希望得到什么结果?我正在等待结果,正如我上面所述,“我的响应是多个JSON行”,并继续发送下一个命令而不超时。当前我的脚本无法继续执行下一个命令。分配
connection=Net::Telnet(…'Promp'
似乎被截断。可能您需要更正。更正。谢谢!它不会永远等待下一个响应吗?文档声明“您可以通过将此值设置为false来禁用超时。在这种情况下,连接尝试最终将在基础connect(2)套接字调用上超时,并出现Errno::ETIMEDOUT错误(但通常仅在几分钟后),但如果没有数据,则从主机读取数据的其他尝试将无限期地进行。”。“因此,在第一步中,我只是尝试将超时值增加到5秒或10秒。我尝试了超时10秒和50秒,但结果是一样的。它只是一直等待下一个响应,直到达到超时。感谢您提供了这个非常全面的答案!我将尝试使用TCPSocket而不是telnet:)
connection.puts("{weather}")
connection.sock.readline