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