如何使用 python 的 telnetlib 在固定时间段内从设备获取数据?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/630217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:30:29  来源:igfitidea点击:

How can I use python's telnetlib to fetch data from a device for a fixed period of time?

pythontelnet

提问by Ben

I'm connecting to a hardware device via telnet. That device is pretty simple in terms of I/O. So I submit a command to it, and after that the device pumps out data one line at a time, once per second. Each line just contains a number.

我正在通过 telnet 连接到硬件设备。该设备在 I/O 方面非常简单。所以我向它提交了一个命令,然后设备一次一行地输出数据,每秒一次。每行只包含一个数字。

So my question is this: if I connect to this device using python's telnetlib, how can I fetch data for a fixed period of time (or a fixed number of lines of data)?

所以我的问题是:如果我使用 python 的 telnetlib 连接到这个设备,我如何获取固定时间段(或固定数量的数据行)的数据?

I've tried using all the various read_ commands, but they all seem to block indefinitely, apart from read_until, which I can't use as the output can't be used to determine when to stop.

我已经尝试使用所有各种 read_ 命令,但它们似乎都无限期地阻塞,除了 read_until 之外,我不能使用它,因为输出不能用于确定何时停止。

(I'm running python 2.5 under Cygwin, btw).

(顺便说一句,我在 Cygwin 下运行 python 2.5)。

Edit: Maybe the real question is, should I be using telnetlib at all for this, or should I just use the socket module?

编辑:也许真正的问题是,我应该为此使用 telnetlib,还是应该只使用套接字模块?

回答by sstock

From your description I'm not clear if you're using telnetlib because the device you're connecting to requires terminal setup provided by telnetor because it seemed like the right thing to do.

根据您的描述,我不清楚您使用 telnetlib 是因为您连接的设备需要 telnet 提供的终端设置,还是因为这似乎是正确的做法。

If the device is as simple as you describe--i.e. not negotiating terminal options on connection--have you considered the asynchatmodule? It would be appropriate for the "send command, read lines" sort of IO pattern you are describing.

如果设备像您描述的一样简单——即不协商连接时的终端选项——您是否考虑过异步模块?它适用于您描述的“发送命令,读取行”类型的 IO 模式。

Alternatively, for something lower-level, you could use the socketmodule to open the connection to the device and then sit in a timed loop and read()the incoming data. If the lines are newline-terminated it should be simple for you to identify each individual number. If you are concerned with blocking, stick this loop in its own thread.

或者,对于较低级别的内容,您可以使用套接字模块打开与设备的连接,然后read()进入定时循环和传入数据。如果这些行以换行符结尾,那么识别每个单独的数字应该很简单。如果您担心阻塞,请将这个循环放在它自己的线程中。

回答by Eli Courtwright

It sounds like blocking isn't really your problem, since you know that you'll only be blocking for a second. Why not do something like:

听起来阻塞并不是你真正的问题,因为你知道你只会阻塞一秒钟。为什么不做这样的事情:

lines_to_read = 10
for i in range(lines_to_read):
    line = tel.read_until("\n")

回答by gimel

In my experience, most such devices use some prompt, in which case Telnet.read_until()is appropriate:

根据我的经验,大多数此类设备使用一些提示,在这种情况下Telnet.read_until()是合适的:

Telnet.read_until(expected[, timeout])

Read until a given string, expected, is encountered or until timeout seconds have passed. When no match is found, return whatever is available instead, possibly the empty string. Raise EOFError if the connection is closed and no cooked data is available.

Telnet.read_until(expected[, timeout])

读取直到遇到预期的给定字符串或直到超时秒数过去。如果找不到匹配项,则返回可用的任何内容,可能是空字符串。如果连接关闭并且没有可用的熟数据,则引发 EOFError 。

If no usable (repetitive) prompt is presented by the device, try Telnet.read_very_eager(), or Telnet.read_very_lazy():

如果设备未显示可用(重复)提示,请尝试Telnet.read_very_eager(),或Telnet.read_very_lazy()

Telnet.read_very_eager()

Read everything that can be without blocking in I/O (eager).

Raise EOFError if connection closed and no cooked data available. Return '' if no cooked data available otherwise. Do not block unless in the midst of an IAC sequence.

Telnet.read_very_eager()

读取所有可以在 I/O 中不阻塞的内容(急切)。

如果连接关闭且没有可用的熟数据,则引发 EOFError。如果没有可用的熟数据,则返回 '' 否则。除非在 IAC 序列中间,否则不要阻塞。

回答by Judge Maygarden

Read lines in a loop until you have either read the required number of lines or the time limit has been reached. However, it doesn't sound like you actual need a telnet library. Why not just use a simple TCP socketfor the connection?

循环读取行,直到您读取了所需的行数或达到了时间限制。但是,听起来您实际上并不需要 telnet 库。为什么不使用简单的 TCP套接字进行连接?