2014-01-20 85 views
0

你好我在python 2.6以下代碼:在python從管道讀取是imposiible

command = "tcpflow -c -i any port 5559" 
port_sniffer = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=1, shell=True) 
while True: 
    line = port_sniffer.stdout.readline() 
    #do some stuff with line 

此代碼的目的是嗅探端口5559進行通信的兩個進程(A和B)之間的通信。

現在讓我描述我具有不同的方案:

1)代碼上面沒有運行: A和B進行通信,並且我可以清楚使用日誌和Linux命令netstat -napl | grep 5559看到表明凝固酶原sses正在通信所需的端口。

2)上面的代碼沒有運行,我通過直接從shell運行tcpflow -c -i any port 5559來嗅探: 我可以清楚地看到控制檯上的通信:-)。

3)上面的代碼正在運行:Proccesses無法通信。 netstat -napl | grep 5559什麼都不打印和日誌給出錯誤!

4)上面的代碼運行在調試模式:我不能似乎能夠行後步驟line = port_sniffer.stdout.readline()

我試圖用一個迭代器,而不是一個while循環(而不是它應該的問題,但仍我指出了)。我也嘗試了不同的bufsize值(無,1和8)。

請幫忙!!

+0

tcpflow不是標準程序。你能提供背景知道什麼'tcpflow -c -i任何端口5559'都可以嗎?它只是將數據轉儲到文件,還是將信息輸出到stdout/stderr? – FuriousGeorge

+0

噢,和FWIW http://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess – FuriousGeorge

+0

tcpflow捕獲tcp數據包,並將它們的消息體(無tcp開銷)寫入文件或控制檯。 -c標誌使它將輸出寫入控制檯。 我寧願使用shell = True,因爲我不知道其他環境可以運行此程序。 – whomaniac

回答

1

所以通過the docs快速閱讀後,我發現這兩個句子:

在Unix上,如果參數表是一個字符串,字符串被解釋爲名稱或程序的 執行路徑

殼參數(默認爲假)指定是否使用 罐殼要執行的程序。如果shell爲True,建議將作爲字符串傳遞,而不是作爲序列傳遞。

在此基礎上,我會建議重新創建你的命令列表:

command = ["tcpflow -c", "-i any port 5559"] #I don't know linux, so double check this line!! 

總的想法是這樣的(也是從文檔):

如果參數表是一個序列,第一項指定命令字符串 ,並且任何附加項目將被視爲殼本身的 的附加參數。也就是說,POPEN不等價的:

Popen(['/bin/sh', '-c', args[0], args[1], ...]) 

此外,似乎從你的進程看,你應該使用communicate()。所以

while True: 
    line = port_sniffer.stdout.readline() 

將成爲

while True: 
    line = port_sniffer.communicate()[0] 

但這記牢記從文檔:

注意讀取的數據在內存中緩衝,所以不要用這種方法如果數據量很大或無限。

+0

感謝您的輸入,但我認爲這不能解決問題。 使用列表或字符串做同樣的事情。 至於溝通,我沒有嘗試過,因爲我知道它阻止。我想要做的是在運行時從tcpflow的stdout中讀取。我不想讓它完成! – whomaniac

0

如果我不得不猜測,我認爲你遇到的問題是你沒有以root身份運行你的程序。如果您希望能夠嗅探其他人的流量(否則這將是一個嚴重的安全漏洞),TCPFlow需要作爲privelaged用戶運行。我寫了下面的程序,他們的工作只是罰款爲您的方案

server.py

#!/usr/bin/python 
import socket 
s = socket.socket() 
host = socket.gethostname() 
port = 12345 
s.bind((host,port)) 
s.listen(5) 
while True: 
    c, addr = s.accept() 
    print 'Connection from', addr 
    c.send('Test string 1234') 
    c.recv(1024) 
    while x != 'q': 
     print "Received " + x 
     c.send('Blah') 
     x = c.recv(1024) 
    print "Closing connection" 
    c.close() 

client.py

#!/usr/bin/python 
import socket, sys 
from time import sleep 
from datetime import datetime 
s = socket.socket() 
host = socket.gethostname() 
port = 12345 
s.connect((host,port)) 
c = sys.stdin.read(1) # Type a char to send to initate the sending loop 
while True: 
    s.send(str(datetime.now())) 
    s.sleep(3) 
    msg = s.recv(1024) 

flow.py

#!/usr/bin/python 
import subprocess 
command = 'tcpflow -c -i any port 12345' 
sniffer = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) 
while True: 
    print sniffer.stdout.readline()