2011-07-13 12 views
3

我是新來的python,但我可以編碼和調試一下。以下問題在過去幾天一直在我的腦海中尋找答案。任何幫助深表感謝。 任務:我想做一個交互式的telnet(我知道有一個telnet庫,但我們沒有因爲各種原因使用它)。 爲此,我使用了subprocess.popenPython:subprocess.stdin.write工作不正常

p = subprocess.Popen(telnet_command, 
         stdin = subprocess.PIPE, 
         stdout = outputfileobj, 
         stderr = errorfileobj) 

我做一個民意調查(),以查看服務器是否已得到連接到會議。一旦我確認,我就繼續寫入標準輸入以進行交互式通信。

inputTxt = 'GET/HTTP/1.1\nHost: ' + hostheader + '\n\n' 
p.stdin.write(inputTxt) 
p.stdin.flush() 

這是問題發生的地方。我得到了http響應(或至少輸出)5/6次,但1/6次,我沒有得到一個輸出,並且子進程終止 - 這是不可能的。

我跑了一個失敗案例的系統跟蹤,請在下面找到相同的。

16129 write(7, "GET/HTTP/1.1\nHost: www.google."..., 37) = 37 
16129 gettimeofday({1310538497, 134474}, NULL) = 0 
16129 futex(0x81993a8, FUTEX_WAKE, 1) = 0 
16129 stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=56, ...}) = 0 
16129 fstat64(4, {st_mode=S_IFREG|0644, st_size=520689, ...}) = 0 
16129 _llseek(4, 520689, [520689], SEEK_SET) = 0 
16129 stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=56, ...}) = 0 
16129 write(4, "2011-07-13 06:28:17,134 : pconns"..., 170) = 170 
16129 futex(0x81d3b30, FUTEX_WAKE, 1) = 0 
16129 waitpid(16198, 0xffa945e8, WNOHANG) = 0 
16129 gettimeofday({1310538497, 135160}, NULL) = 0 
16129 fstat64(6, {st_mode=S_IFREG|0644, st_size=81, ...}) = 0 
16129 fstat64(6, {st_mode=S_IFREG|0644, st_size=81, ...}) = 0 
16129 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf74b9000 
16129 _llseek(6, 0, [0], SEEK_SET)  = 0 
16129 fstat64(6, {st_mode=S_IFREG|0644, st_size=81, ...}) = 0 
16129 _llseek(6, 0, [0], SEEK_CUR)  = 0 
16129 read(6, "Trying 74.125.236.48...\nConnecte"..., 4096) = 81 
16129 read(6, "", 4096)     = 0 
16129 close(6)       = 0 
16129 munmap(0xf74b9000, 4096)   = 0 
16129 gettimeofday({1310538497, 135778}, NULL) = 0 
16129 futex(0x81993a8, FUTEX_WAKE, 1) = 0 
16198 <... select resumed>)   = 1 (in [0]) 
16198 read(0, "GET/HTTP/1.1\nHost: www.google."..., 8191) = 37 
16129 stat64("/etc/localtime", <unfinished ...> 
16198 ioctl(1, TCFLSH, 0)    = -1 ENOTTY (Inappropriate ioctl for device) 
16129 <... stat64 resumed> {st_mode=S_IFREG|0644, st_size=56, ...}) = 0 
16198 select(4, [0 3], [3], [3], {0, 0}) = 1 (out [3], left {0, 0}) 
16129 fstat64(4, {st_mode=S_IFREG|0644, st_size=520859, ...}) = 0 
16198 send(3, "GET/HTTP/1.1\r\nHos\377\363\377\375\6", 24, 0 <unfinished ...> 
16129 _llseek(4, 520859, <unfinished ...> 
16198 <... send resumed>)    = 24 
16198 select(4, [0 3], [3], [3], {0, 0} <unfinished ...> 
16129 <... _llseek resumed> [520859], SEEK_SET) = 0 
16198 <... select resumed>)   = 1 (out [3], left {0, 0}) 
16198 send(3, ": www.google.com\r\n\r\n", 20, 0 <unfinished ...> 
16129 stat64("/etc/localtime", <unfinished ...> 
16198 <... send resumed>)    = 20 

如果你仔細看線16198發送(3, 「GET/HTTP/1.1 \ r \ nHos \ 377 \ 363 \ 377 \ 375 \ 6」,24日,在跟蹤0,字符串「Hos t」被替換爲一些「Hos \ 377 \ 363 \ 377 \ 375 \ 6」。我不確定爲什麼偶爾會出現這種情況,並且這會關閉我建立的telnet連接。請讓我知道你是否需要更多的數據

+0

您爲什麼要向telnet服務器發出HTTP請求?或者您只是在80處測試連接到google.com? – cyraxjoe

+0

我們試圖檢查服務器是否支持持久連接(可以在連接後發佈多個請求)。 –

回答

1

如果你嘗試使用communicate()方法發送數據到子進程而不是使用stdin,那麼怎麼辦?Python's documentation

警告:通信(),而不是.stdin.write,.stdout.read或 .stderr.read避免死鎖由於任何其他OS管的 緩衝器填滿和阻斷子處理。

試試這個:

p.communicate(input='GET/HTTP/1.1\nHost: ' + hostheader + '\n\n') 
+0

是的,我可以嘗試,但問題是它不是我想要在該打開的過程中執行的一個命令。相反,我需要在該會話中執行很多操作。這是我決定使用poll()和stdin的第一個原因。 –

1

雖然溝通是更好的,如果你真的要使用stdin.write您可以使用電話無阻塞:

fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)

爲了更好的理解閱讀:

io non blocking