-->

Python读物,直到从远程登录空字符(Python reading until null char

2019-10-21 01:50发布

我远程登录到我的服务器,它解答了我的消息,并在每条消息的末尾附加hex00(空字符)不能被读取。 我试图通过,并通过搜索,但似乎无法使其工作,一个简单的例子:

from telnetlib import Telnet
connection = Telnet('localhost', 5001)
connection.write('aa\n')
connection.read_eager()

这将返回的输出:

'Fail - Command aa not found.\n\r'

而应该是有某事喜欢:

'Fail - Command aa not found.\n\r\0'

有没有什么办法让串字符的结束? 我能得到字节输出在角色故意错过了什么?

00字符有:

Answer 1:

我在这个同样的问题绊倒试图从RS232-TCP / IP转换器使用telnet获取数据时 - 在telnetlib会从消息打压每一个为0x00。 正如弗雷德里克·约翰逊很好回答,这是telnetlib被实施的方式。

一个解决办法是覆盖process_rawq()从telnetlib的远程登录类函数不吃掉所有的空字符:

import telnetlib
from telnetlib import IAC, DO, DONT, WILL, WONT, SE, NOOPT

def _process_rawq(self):
    """Alteração da implementação desta função necessária pois telnetlib suprime 0x00 e \021 dos dados lidos
    """
    buf = ['', '']
    try:
        while self.rawq:
            c = self.rawq_getchar()
            if not self.iacseq:
#                if c == theNULL:
#                    continue
#                if c == "\021":
#                    continue
                if c != IAC:
                    buf[self.sb] = buf[self.sb] + c
                    continue
                else:
                    self.iacseq += c
            elif len(self.iacseq) == 1:
                # 'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]'
                if c in (DO, DONT, WILL, WONT):
                    self.iacseq += c
                    continue

                self.iacseq = ''
                if c == IAC:
                    buf[self.sb] = buf[self.sb] + c
                else:
                    if c == SB: # SB ... SE start.
                        self.sb = 1
                        self.sbdataq = ''
                    elif c == SE:
                        self.sb = 0
                        self.sbdataq = self.sbdataq + buf[1]
                        buf[1] = ''
                    if self.option_callback:
                        # Callback is supposed to look into
                        # the sbdataq
                        self.option_callback(self.sock, c, NOOPT)
                    else:
                        # We can't offer automatic processing of
                        # suboptions. Alas, we should not get any
                        # unless we did a WILL/DO before.
                        self.msg('IAC %d not recognized' % ord(c))
            elif len(self.iacseq) == 2:
                cmd = self.iacseq[1]
                self.iacseq = ''
                opt = c
                if cmd in (DO, DONT):
                    self.msg('IAC %s %d',
                        cmd == DO and 'DO' or 'DONT', ord(opt))
                    if self.option_callback:
                        self.option_callback(self.sock, cmd, opt)
                    else:
                        self.sock.sendall(IAC + WONT + opt)
                elif cmd in (WILL, WONT):
                    self.msg('IAC %s %d',
                        cmd == WILL and 'WILL' or 'WONT', ord(opt))
                    if self.option_callback:
                        self.option_callback(self.sock, cmd, opt)
                    else:
                        self.sock.sendall(IAC + DONT + opt)
    except EOFError: # raised by self.rawq_getchar()
        self.iacseq = '' # Reset on EOF
        self.sb = 0
        pass
    self.cookedq = self.cookedq + buf[0]
    self.sbdataq = self.sbdataq + buf[1]
telnetlib.Telnet.process_rawq = _process_rawq

然后覆盖在Telnet类的方法:

telnetlib.Telnet.process_rawq = _process_rawq

这解决了这个问题对我来说。



Answer 2:

此代码( http://www.opensource.apple.com/source/python/python-3/python/Lib/telnetlib.py )似乎忽略空字符。 那真的是正确的行为?

def process_rawq(self):
    """Transfer from raw queue to cooked queue.

    Set self.eof when connection is closed.  Don't block unless in
    the midst of an IAC sequence.

    """
    buf = ''
    try:
        while self.rawq:
            c = self.rawq_getchar()
            if c == theNULL:
                continue
:
:

process_rawq然后又称为例如通过read_until

def read_until(self, match, timeout=None):
    """Read until a given string is encountered or until timeout.

    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.

    """
    n = len(match)
    self.process_rawq()
    :
    :

我也想接收空字符。 在我的特定情况下它标志着一个多消息的结束。

因此,答案似乎是,这是预期的行为为库代码编写。

FWIW https://support.microsoft.com/en-us/kb/231866规定:

通信是通过TCP / IP建立,是基于一个网络虚拟终端(NVT)。 在客户端,Telnet程序负责将传入NVT代码由客户端的显示装置,以及用于转换客户端生成的键盘代码转换成呼出NVT代码理解代码。

的NVT使用7位代码字符。 的显示装置中,被称为在RFC打印机,只需要显示由7位代码所表示的标准打印的ASCII字符,并识别和处理某些控制代码。 7位字符被作为最显著位设定为零的8位字节传输。 的端部的行作为后跟一个换行(LF)回车(CR)发送。 如果你想传递一个实际回车,这是作为一个回车跟一个NUL传输(所有位零)字符。

Name     Code   Decimal Value   
Function NULL   NUL 0   No operation


文章来源: Python reading until null character from Telnet