[英]Reading from pipe in python is imposiible
您好,我在python 2.6中有以下代码:
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
清楚地看到它netstat -napl | grep 5559
netstat -napl | grep 5559
显示进程正在所需的端口上进行通信。
2)上面的代码未运行,我通过直接从shell运行tcpflow -c -i any port 5559
嗅探:我可以清楚地在控制台上看到通信:-)。
3)上面的代码正在运行:过程无法进行通信。 netstat -napl | grep 5559
netstat -napl | grep 5559
打印任何内容,日志会显示错误!!!
4)上面的代码在调试模式下运行:我似乎无法在line = port_sniffer.stdout.readline()
我尝试使用迭代器而不是while循环(这并不重要,但仍在指出)。 我还尝试了bufsize的其他值(none,1和8)。
请帮忙!!
因此,快速浏览文档后,我发现了以下两个句子:
在Unix上,如果args是字符串,则将该字符串解释为要执行的程序的名称或路径
和
shell参数(默认为False)指定是否将shell用作要执行的程序。 如果shell为True,建议将args作为字符串而不是序列传递。
基于此,我建议将您的命令重新创建为列表:
command = ["tcpflow -c", "-i any port 5559"] #I don't know linux, so double check this line!!
总体思路是这样的(也来自文档):
如果args是序列,则第一项指定命令字符串,任何其他项都将被视为shell本身的其他参数。 也就是说,Popen等效于:
Popen(['/bin/sh', '-c', args[0], args[1], ...])
另外 ,似乎要从您的进程中读取,应该使用communicate()
。 所以
while True:
line = port_sniffer.stdout.readline()
会成为
while True:
line = port_sniffer.communicate()[0]
但是请记住以下来自文档的注释:
注意读取的数据缓存在内存中,因此,如果数据大小很大或没有限制,请不要使用此方法。
如果我不得不猜测,我认为您遇到的问题是您没有以root用户身份运行程序。 如果您希望能够嗅探其他人的流量,则必须以特权用户身份运行TCPFlow(否则这将是一个严重的安全漏洞)。 我编写了以下程序,它们在您的情况下工作正常
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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.