以下是:使用子流程获得实时输出
我正在尝试使用子流程实时捕获iperf3的输出(在windows上使用python 3.6(。目标是让iperf3会话持续运行,并获取数据以更新实时图。
我基于引用的问题创建了一个实现(请参阅文章末尾的代码(,但代码仍在等待第一个"readline"调用,以完成iperf3会话。
输出和所需行为
我的代码返回输出:
Iperf test
Popen returns after: 0.012966156005859375 seconds
Readline 0 returned after: 3.2275266647338867 seconds, line was: Connecting to host 10.99.99.21, port 5201
Readline 1 returned after: 3.2275266647338867 seconds, line was: [ 4] local 10.99.99.7 port 55563 connected to 10.99.99.21 port 5201
Readline 2 returned after: 3.2275266647338867 seconds, line was: [ ID] Interval Transfer Bandwidth
Readline 3 returned after: 3.2275266647338867 seconds, line was: [ 4] 0.00-0.50 sec 27.4 MBytes 458 Mbits/sec
Readline 4 returned after: 3.2275266647338867 seconds, line was: [ 4] 0.50-1.00 sec 29.0 MBytes 486 Mbits/sec
Exited
输出显示,第一个readline调用直到3秒后iperf会话完成后才返回。所需的行为是,只要iperf3完成了第一个0.5秒的报告间隔,读线调用0、1和2几乎立即返回,并且读线调用#3在大约0.5秒后返回。
代码
import subprocess
import time
if __name__ == "__main__":
print('Iperf test')
tref = time.time()
reads_to_capture = 5
times = [0] * reads_to_capture
lines = [''] * reads_to_capture
interval = 0.5
ip = '10.99.99.21' # Iperf server IP address
process = subprocess.Popen(f'iperf3 -c {ip} -f m -i {interval} -t 3', encoding = 'utf-8',
stdout=subprocess.PIPE)
print(f'Popen returns after: {time.time() - tref} seconds')
cnt = 0
while True:
output = process.stdout.readline()
if cnt < reads_to_capture: # To avoid flooding the terminal, only print the first 5
times[cnt] = time.time() - tref
lines[cnt] = output
cnt = cnt + 1
if output == '':
rc = process.poll()
if rc is not None:
break
rc = process.poll()
for ii in range(reads_to_capture):
print(f'Readline {ii} returned after: {times[ii]} seconds, line was: {lines[ii].strip()}')
print('Exited')
很抱歉我回答得太晚了。有一个适用于Iperf3的API,幸运的是,它附带了标准的Iperf3构建/安装。
这个API允许python获取iperf3的公共输出。
我让你看看iperf3的python包装器的官方网站。它附带了一些简单的例子供您使用。希望我能给你一个答案。
https://iperf3-python.readthedocs.io/en/latest/index.html
为了获得从iperf3到subprocess.Popen
的实时输出,您需要在iperf3命令中使用--forceflush
标志。在iperf 3.1.5中引入了--forceflush
标志,不幸的是,官方编译的iperf3.exe文件直到iperf 3.1.3才有。
两种解决方案,
- 获取iperf>=3.1.5非官方路线,如:https://files.budman.pw/
- 使用linux的iperf3
附我的代码:
import subprocess
my_iperf_process = subprocess.Popen(["iperf3","-c","192.168.0.1","--forceflush"],stdout=subprocess.PIPE)
for line in my_iperf_process.stdout:
print(line)
--forceflush
:的帮助信息
--forceflush force flushing output at every interval