%EC%9D%84%20%ED%86%B5%ED%95%B4%20AS400%20%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%97%90%20Telnet%20%EC%97%B0%EA%B2%B0.png)
나는 AS/400 서버와 통신하기 위해 Telnetlib(Python)을 사용하여 Telnet 클라이언트(포트 23)를 생성합니다. 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년 이후 제품을 출시하지 않았습니다. 제품 라인은 나중에 System i, i5가 된 iSeries 시스템으로 대체(또는 관점에 따라 이름이 변경)되었지만 OS는 여전히 OS/400이었습니다. 하드웨어 제품 라인은 pSeries 시스템과 합병되어 Power Systems가 되었습니다. OS는 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 텔넷을 사용하도록 구성되었을 수도 있지만 이는 아마도 쉽지 않은 일입니다. 그러나 TN5250 지원은 거의 확실합니다. 대신 그것으로 연결해 보세요.
답변2
*nix 텔넷 연결처럼 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
아래는 귀하의 질문에 첨부된 댓글에 제가 묻고자 했던 질문입니다. 그러다가 당신을 알아차렸어요교차 게시됨스택 오버플로에 대한 질문입니다. 게시물을 교차하지 마십시오.
거기에서 나는 당신이 게시한 것을 발견했습니다.붙여넣기 상자댓글로. 그로 인해 내 의견이 답변으로 바뀌게 되었습니다.
붙여넣기 상자에서 AS/400의 프롬프트는 마침표 사이에 공백을 표시합니다. 질문의 코드에는 점 사이에 공백이 없습니다. 거기에 공백을 넣으면 코드가 작동할 가능성이 높습니다.
후손을 위해(이런 종류의 정보를 미리 제공하면 좋은 답변을 더 빨리 받을 가능성이 높아집니다):
AS/400에 올바른 줄 끝을 보내고 있습니까?
AS/400은 어떤 OS를 실행하고 있습니까?
AS/400 텔넷 로그인 프롬프트에는 실제로 점과 공백이 모두 포함되어 있습니까?
환영 배너나 이와 유사한 것을 기대하시나요?
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"