2010-10-22 86 views
3

我正在使用Python模塊telnetlib創建一個telnet會話(與一個國際象棋服務器),並且我遇到了一個問題,我真的無法環繞我的大腦。下面的代碼完美地起作用:Python telnetlib:令人驚訝的問題

>>> 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 
+0

嘗試'print foo()' – ghostdog74 2010-10-22 23:11:59

+0

沒有區別。 – ptz 2010-10-23 09:41:24

+1

我發現,如果不是使用read_very_eager(),而是使用read_until(),它確實有效。它應該是關於傳輸數據的協議和方式,而我沒有必要的技術背景。 – ptz 2010-10-23 09:59:41

回答

5

之所以當您手動,但不嘗試一下當一個功能是因爲當您手動嘗試一下,服務器有這個工程有足夠的時間對登錄做出反應並將數據發回。當它全部在一個功能中時,您將密碼發送到服務器,並且永遠不會等待服務器回覆足夠長的時間。

如果你喜歡一個(可能更正確)的技術答案:

在文件telnetlib.py(C:\ python26 \ LIB \ telnetlib.py我的Windows計算機上),函數調用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], [], []) 

這樣做什麼是非常簡單的:如果有-anything-從我們的插座(服務器已回答)讀取,它會返回true,否則它會返回False。

因此,read_very_eager(self)所做的是:檢查是否有任何可讀的內容。如果存在,則從套接字讀取,否則返回一個空字符串。

如果你看read_some(self)的代碼,你會發現它不檢查是否有任何數據可供閱讀。它會嘗試閱讀,直到有可用的東西,這意味着如果服務器在回答您之前需要100毫秒,它會在返回答案之前等待100毫秒。

3

我和你有同樣的麻煩,不幸的是,select.select,我在while循環中,直到我能夠讀取,然後調用read_some()不起作用,我仍然只讀取實際輸出的1%。如果我在讀取read_very_eager()之前先寫入time.sleep(10),它似乎可以工作......這是一種非常粗糙的做事方式,但它確實有效。我希望有更好的答案,並且我希望我有更多的聲望點,所以我可以迴應用戶387821,看看他是否有任何額外的提示。