从python中的管道读取是不可能的

2024-10-04 03:27:56 发布

您现在位置:Python中文网/ 问答频道 /正文

您好,我在Python2.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显示进程正在所需的端口上通信。在

2)上面的代码没有运行,我通过直接从shell运行tcpflow -c -i any port 5559进行嗅探: 我可以清楚地看到控制台上的通信:-)。在

3)以上代码正在运行:进程无法通信。netstat -napl | grep 5559不打印任何内容,日志会给出错误!!!在

4)上面的代码是在调试模式下运行的:我似乎无法在line = port_sniffer.stdout.readline()行之后执行步骤

但我还是用了一个循环来代替。我还尝试了bufsize的不同值(none、1和8)。在

请帮忙!!在


Tags: 端口代码truereadline进程portstdoutline
2条回答

如果非要我猜的话,我想你现在的问题是你没有以根用户身份运行程序。如果您希望能够嗅出其他人的流量(否则这将是一个严重的安全漏洞),那么TCPFlow需要以私有用户的身份运行。我写了下面的程序,它们对你的场景起到了很好的作用

在服务器.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()

在客户端.py在

^{pr2}$

在流动.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()

所以在快速阅读了the docs之后,我发现了以下两个句子:

On Unix, if args is a string, the string is interpreted as the name or path of the program to execute

以及

The shell argument (which defaults to False) specifies whether to use the shell as the program to execute. If shell is True, it is recommended to pass args as a string rather than as a sequence.

基于此,我建议将命令重新创建为列表:

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

总的想法是这样的(同样来自文档):

If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself. That is to say, Popen does the equivalent of:

^{pr2}$

另外,似乎要从进程中读取,应该使用communicate()。所以

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

会变成

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

但请记住文件中的以下注释:

Note The data read is buffered in memory, so do not use this method if the data size is large or unlimited.

相关问题 更多 >