3

Python モジュール telnetlib を使用して telnet セッションを作成しています (チェス サーバーを使用)。次のコードは完全に機能します。

>>> f = login("my_server") #code for login(host) below.
>>> f.read_very_eager()

これにより、ログイン時にサーバーが通常出力するすべてが吐き出されます。ただし、関数内に配置してから呼び出すと、次のようになります。

>>> def foo():
...   f = login("my_server")
...   return f.read_very_eager()
...
>>> foo()

何も取得しません (空の文字列)。ログインが正常に行われていることは確認できるのですが、なぜか文字が見えません。では、どこで飲み込まれるのでしょうか。

どうもありがとう。

完全を期すために、ログイン(ホスト)は次のとおりです。

def login(host, handle="guest", password=""):
try:
    f = telnetlib.Telnet(host) #connect to host
except:
    raise Error("Could not connect to host")
f.read_until("login: ")
try:
    f.write(handle + "\n\r")
except:
    raise Error("Could not write username to host")
if handle == "guest":
    f.read_until(":\n\r")
else:
    f.read_until("password: ")
try:
    f.write(password + "\n\r")
except:
    raise Error("Could not write password to host")
return f
4

2 に答える 2

5

手動で試してみると機能するのに関数内では機能しない理由は、手動で試してみると、サーバーがログインに反応してデータを送り返すのに十分な時間があるためです。すべてが 1 つの機能に組み込まれている場合は、パスワードをサーバーに送信し、サーバーが応答するのを待つ必要はありません。

(おそらくより正確な)技術的な回答が必要な場合:

ファイル telnetlib.py (私の Windows コンピューターでは c:\python26\Lib\telnetlib.py) で、関数read_very_eager(self)が呼び出されself.sock_avail()、関数sock_avail(self)は次のことを行います。

def sock_avail(self):
    """Test whether data is available on the socket."""
    return select.select([self], [], [], 0) == ([self], [], [])

これが行うことは非常に単純です。ソケットから読み取るものがある場合 (サーバーが応答した場合) は True を返し、それ以外の場合は False を返します。

だから、何をすべきかread_very_eager(self): 読むことができるものがあるかどうかを確認してください。ある場合はソケットから読み取り、そうでない場合は単に空の文字列を返します。

のコードを見ると、read_some(self)読み取り可能なデータがあるかどうかをチェックしていないことがわかります。利用可能なものがあるまで読み取りを試みます。つまり、サーバーが応答するまでにたとえば 100 ミリ秒かかる場合、応答を返す前に 100 ミリ秒待機します。

于 2011-01-26T14:20:31.633 に答える
3

私はあなたと同じ問題を抱えていますが、残念ながらselect.selectの組み合わせは、私が読むことができるようになるまでしばらくの間ループしていて、read_some()を呼び出しても機能せず、まだ1%しか読んでいません実際の出力。読んでread_very_eager()を実行する前にtime.sleep(10)をオンにすると、動作するように見えます...これは非常に大雑把な方法ですが、動作します。 user387821に返信して、彼に追加のヒントがあるかどうかを確認できるように、レピュテーションポイントがもっとあればいいのにと思います。

于 2012-11-07T02:00:17.743 に答える