我有一个IP列表(从Python Scapy中的traceroute生成),我需要发送3个ping来测量每跳的平均时间。我的第一种方法是使用套接字构建ICMP请求并测量响应时间。但是,当ping多个主机时,它是不准确和缓慢的。我确实尝试使用正常的Linux ping,但是我的for i
循环在等待响应时被阻塞,显然我希望所有的ping请求同时发出。
所以我正在寻找一种在Linux中使用fping
的方法,我给出了一个IP列表,然后让它完成构建数据包的工作。但是我不确定如何将参数列表传递给shell命令或在完成后将数据返回到数组中进行进一步处理。
任何提示感谢!
我不太了解fping
,但像这样的东西…
import subprocess
CMD = ['fping', 'param1', 'param2']
result = subprocess.check_output(CMD)
…将运行fping param1 param2
,并在fping
进程终止后将输出作为字符串放入result
变量。
您可以使用result.splitlines()
将输出分成几行。
下面是一个快速的一行示例,使用ping
获取到localhost的三个ping次数…
>>> [line.rpartition('=')[-1] for line in subprocess.check_output(['ping', '-c', '3', 'localhost']).splitlines()[1:-4]]
['0.028 ms', '0.023 ms', '0.025 ms']
下面的函数解析fping
的输出并返回一个包含每个主机可用性的字典:
import subprocess
from typing import List, Dict
def ping(hosts: List[str], timeout: int = 500) -> Dict[str, bool]:
command = ["fping", "-t", str(timeout)] + hosts
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
parse = lambda stream: [
line.split(" ")
for line
in stream.read().decode("UTF-8").split("n")
if len(line) != 0
]
lines = parse(proc.stdout) + parse(proc.stderr)
return {p[0]: p[-1] == "alive" for p in lines if p[1] == 'is'}
print(ping(["google.com", "asdfasdfasdf1234.com", "stackoverflow.com"]))
# {'google.com': True, 'stackoverflow.com': True, 'asdfasdfasdf1234.com:': False}