我需要一些提示/帮助,如何将多行响应读入变量。 我当前的命令导致多线响应但在此之后我得到超时。
以下是我的连接设置方式:
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>'
我的回答是多条JSON行,如下所示:
{"City":"Tallinn", "Degrees":"23"}
{"City":"Berlin", "Degrees":"23"}
{"City":"Helsinki", "Degrees":"23"}
{"City":"Stockholm", "Degrees":"23"}
答案 0 :(得分:2)
对于某些协议,可以在创建Telnet对象并使用cmd()调用时指定一次“提示”选项;对于其他人,您必须指定响应序列以查找每个cmd()调用的匹配选项,或直接调用puts()和waitfor();对于其他人,你将不得不使用sysread()而不是waitfor()并自己解析服务器响应。
当与Net::Telnet#cmd
method's documentation结合使用时更有意义,TCPSocket
表示方法:
向主机发送一个字符串,并读入所有收到的数据,直到看到提示或其他匹配的序列。
您未指定自定义Prompt
或Match
选项,因此#cmd
正在等待服务器中与默认Net::Telnet
提示符匹配的内容({ {1}})表示消息的结束。
如果消息没有以这种提示结束,那么它将永远等待。
如果服务器确实发送某种提示以表明它已完成发送数据,您应该键入下一个命令,则可以将与其匹配的正则表达式传递给/[$%#>] \z/n
初始化程序。例如,如果服务器提示您Net::Telnet
,则可以使用:
command:
如果没有提示,但您正在等待特定字符序列的响应,则可以在致电connection = Net::Telnet.new(
"Prompt" => /command: \z/,
# …
)
时明确指定Match
选项。例如,如果您的响应是单个JSON数组,那么它将以#cmd
结束,因此您可以使用它:
]
connection.cmd("String" => "{weather}", "Match" => "]") { |c| print c }
并使用Net::Telnet
如果没有提示且没有已知结尾,您可以尝试使用TCPSocket
对象的基础here来读取数据而不使用Net::Telnet
:
#cmd
此时,使用connection.puts("{weather}")
connection.sock.readline
优于普通Net::Telnet
可能没什么好处。
答案 1 :(得分:1)
您将超时设置为一秒,并且不指定str
是什么。您可以尝试增加超时值,甚至可以将其设置为false。 Believieng它是.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"