2

このポスターと同様の問題があります。

Python telnetlib: 驚くべき問題

応答とその下の私の応答に注意してください。

基本的に、telnetlib では、読み取り関数を呼び出したときに応答全体を読み取らせてくれません。

while ループで select.select([telnetobject],[],[]) を使用した後に telnet.read_very_eager() を呼び出して、読み取りが可能であることを確認すると、取得できるのは数文字だけです。これまでのところ、私が思いつくことができる唯一の解決策は time.sleep() を使用することですが、それはあまりにも粗雑な解決策であり、より適切なものを探しています。助けていただければ幸いです...

4

2 に答える 2

0

私は同じ問題を抱えていたと思います。この情報が役立つことを願っています。私の場合、Maya の mel および python ポートに接続しているので、この経験があなたとあなたの状況に役立つかどうかはわかりません。

  • この回答は、I/OIが行おうとしていたためにTelnet/telnetlibがまったく必要ないことを示し、asynchatを推奨しました。

  • サーバー側に表示されたすべての出力がクライアントで読み取れるわけではないことが判明しました。セカンドオピニオンとしてasynchatを使用し、どのように送信しても「print 'Complete Command'」からの出力をまだ受け取っていないことに気付くまで、それが起こり得ることだとは思いもしませんでした. (「print 'Complete Command'」と書き、結果を読み取って、前のコマンドがいつ完了したかを確認しようとしていました。)

最終的に、クライアントが読み取り可能な出力を生成する mel の警告コマンドを呼び出しました。無害なデータを警告として送信するのはかなり不快ですが、幸いこれは内部ツール用です。

  • telnetlib は書き込みをキューに入れないようです。したがって、2 つのコマンドを続けて送信するという私の計画 (実際のコマンド、次に「コマンド完了」アナウンス) が常に機能するとは限りません。したがって、telnetlib の出力の読み取りは、read_until() の出力を正確に知っている場合、または出力が完了したと思われるまでスリープする意思がある場合にのみ機能するようです。ただし、 asynchat.push() は確実に期待どおりに書き込みをキューに入れます。

私はまだこれを理解しているので、巨大な塩の粒で取られるサンプル:

class mayaClient(asynchat.async_chat) :


... 

def __init__(self, sock, clientType):

    asynchat.async_chat.__init__(self, sock=sock)

    self.clientType = clientType
    self.ibuffer = []
    self.obuffer = ""
    self.set_terminator("\r\n")
    self.cumulativeResponse = ""


@classmethod
def withSocket(cls, host, clientType, log) :

    melSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    portNumber = cls.MEL_PORT_NUMBER if clientType == cls.MEL else cls.PYTHON_PORT_NUMBER
    melSocket.connect((host, portNumber))   
    return cls(melSocket, clientType, log)


#############################################################
# pushAndWait
#############################################################
def pushAndWait(self, command, timeout=60) :
    """
    ACTION:     Push a command and a "command complete" indicator
                If command completed, return number of milliseconds it took
                If command timed out without completing, return -1

    INPUT:      command as string
                description (optional) as string for more informative logging
                timeout in seconds as int after which to give up

    OUTPUT:     X milliseconds if command completed
                -1 if not

    """

    self.found_terminator()

    incrementToSleep = .001

    self.push("%s\r\n"%command)

    responseToSeek = "Command Complete"
    self.push('Whatever command is going to create readable output for %s`); \r\n'%responseToSeek)

    timeSlept = 0
    while responseToSeek not in self.currentBufferString() and timeSlept < timeout :
        self.read()
        timeSlept += incrementToSleep
        time.sleep(incrementToSleep)

    if responseToSeek in self.currentBufferString() :
        return timeSlept

    return -1


#############################################################
# read
#############################################################
def read(self) :
    """
    ACTION:     Reads the current available output
                and stores it in buffer

    """

    try :

        self.collect_incoming_data(self.recv(1024))

    except Exception, e :

        # Don't worry about it -- just means there's nothing to read
        #
        pass


#############################################################
# currentBuffer
#############################################################
def currentBuffer(self) :

    return self.ibuffer


#############################################################
# currentBufferString
#############################################################
def currentBufferString(self) :

    return "".join(self.ibuffer)


#############################################################
# collect_incoming_data
#############################################################
def collect_incoming_data(self, data):
    """Buffer the data"""

    self.ibuffer.append(data)   


#############################################################
# found_terminator
#############################################################
def found_terminator(self):

    print "Clearing --%s...-- from buffer"%self.currentBufferString()[0:20]
    self.ibuffer = []
于 2013-03-01T23:09:32.777 に答える