我使用 telnetlib - Python - 创建 telnet 客户端 - 端口 23 - 与 AS/400 服务器通信。使用 telnet 命令通信没有问题,但使用 telnetlib 我没有收到任何消息。
这是我的代码:
import getpass
import sys
import telnetlib
HOST = raw_input("HOST : ")
user = raw_input("Enter your remote account: ")
password = getpass.getpass()
try:
tn = telnetlib.Telnet(HOST)
tn.read_until("User..... ")
tn.write(user + "\r")
tn.read_until("Password..... ")
tn.write(password + "\r")
print tn.read_all()
except:
print "Error"
谢谢。
答案1
IBM 已经养成了更改名称的习惯。您谈论的机器很可能不是真正的 AS/400,它运行的是 OS/400。自 2000 年以来,IBM 就再也没有出货过这样的机器。产品线被 iSeries 系统取代(或重命名,取决于您的观点),后来成为 System i,然后是 i5,但操作系统仍然是 OS/400。硬件产品线与 pSeries 系统合并,成为 Power Systems。操作系统变成了 i5/OS,现在在最新版本 7.1 下,它正式被称为“IBM i”。下一代硬件 Pure Systems 也可以运行 IBM i OS。因此,您的服务器很可能实际上是 System i 或 Power System,但 IT 人员经常继续称它们为 AS/400,甚至认为它们是 AS/400。作为一个整体,这个产品线家族树通常被称为 IBM 的中端系统。
IBM 中端系统最初采用的是 IBM 5250 型终端。后续型号仍使用所谓的 5250 协议,该协议在某些方面类似于 IBM 大型机使用的 3270 协议。它是一种面向块的协议,通常一次传输整个屏幕,通常根据字符的原始颜色通俗地称为“绿屏”。虽然您的服务器可能配置为使用 VTxxx telnet,但这可能不太可能。但几乎可以肯定支持 TN5250。请尝试使用该协议进行连接。
答案2
您不能像对待 *nix telnet 连接那样对待 AS/400 连接。不要使用 read_until(),而是尝试使用 read_very_eager() 来获取整个屏幕(包括将光标定位在“User....”字段开头的 ANSI 转义序列),然后 write() 您在手动登录时要输入的确切内容。我还发现,为了在连接后显示登录屏幕,您需要先输入一个换行符。我不知道为什么会这样,但这对我来说很有效。
import getpass
import sys
import telnetlib
HOST = raw_input("HOST : ")
user = raw_input("Enter your remote account: ")
password = getpass.getpass()
try:
tn = telnetlib.Telnet(HOST)
tn.write('\n')
tn.read_very_eager()
tn.write(user)
tn.write('\t') # tab into the next field
tn.write(password)
tn.write('\r') # 'enter' key
except:
print "Error"
最后一件事:请记住,AS/400 不会在屏幕末尾发送 EOF 字符,因此 read_all() 将挂起并且永远不会返回。您可以尝试使用 read_until(),但由于从服务器返回的数据可能被破坏并且充满 ANSI 转义序列,因此无法保证找到您想要的内容。显而易见的解决方案似乎是将 read_very_eager() 放在一个 while 循环中,当 read_very_eager() 返回空字符串时终止。但是,这有其自身的问题,因为服务器可能会在转到下一个全屏之前返回各种状态消息或其他部分屏幕。唯一完整的解决方案可能是不断解析服务器返回的数据并跟踪当前屏幕的样子(即终端仿真和屏幕抓取)或只是在写入和读取之间添加一些 time.sleep() 命令。
答案3
以下是我原本想在你的问题的评论中提出的问题。然后我注意到你交叉发布将问题发送至 Stack Overflow。请不要交叉发布。
我发现你在那里发布了一个糊盒在评论中。这促使我将我的评论改为答案。
在您的粘贴箱中,AS/400 的提示显示句点之间的空格。在您的问题中的代码中,点之间没有空格。在那里放置空格很可能会让您的代码正常工作。
为了后人(提前提供此类信息将使您更有可能更快地收到好的答复):
您确定向 AS/400 发送了正确的行尾吗?
AS/400 运行什么操作系统?
AS/400 telnet 登录提示是否真的包含所有这些点,后面跟着一个空格?
您是否期待看到欢迎横幅或类似的东西?
如果在之前发送命令会发生什么read_all
?
AS/400 上的日志显示了什么?
答案4
尝试 Python Expect ( pexpect
) 模块。按照密码质量.py脚本作为示例。它也应该包含在 pexpect 模块中。
这是一个未经测试修改你的脚本:
import getpass
import pexpect
import sys
HOST = raw_input("HOST : ")
user = raw_input("Enter your remote account: ")
password = getpass.getpass()
try:
tn = pexpect.spawn('telnet %s'%(HOST))
tn.logfile = file ("LOG.TXT","wb")
i = tn.expect([pexpect.TIMEOUT, '[Uu]ser..... '])
if i == 0: # Timeout
print 'ERROR!'
print 'telnet could not login. Here is what telnet said:'
print tn.before, tn.after
sys.exit (1)
tn.sendline(user)
tn.expect (['[Pp]assword..... '])
tn.sendline(password)
except:
print "Error"