%20Telnet%20%E9%80%A3%E6%8E%A5%E5%88%B0%20AS400%20%E7%B3%BB%E7%B5%B1.png)
我使用 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 已經養成了更改名稱的習慣。您所談論的機器很可能不是真正運行 OS/400 的 AS/400。 IBM 自 2000 年以來就沒有發貨過。硬體產品線與 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
) 模組。跟著passmass.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"