通过Popen帮助ping

2024-10-01 11:25:05 发布

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

我正在开发一个软件来监控不同地点的通讯。 原理很简单:每秒发送ping并实时显示结果(毫秒延迟、丢包等)

还有一点很重要,我是从Linux运行软件的,所以为了从我的软件ping,我选择亚过程。波本是的,因为打开套接字需要您以root用户的身份登录。我不想让每个人都有访问服务器的权限。。在

以下是负责ping的类:


 class WorkerThread(QThread):
  def __init__(self,receiver,sitename):
    QThread.__init__(self)

    global time_manager
    time_manager[sitename] = [time.time(),0,0] #for statistic purpeses

    self.stopped = 0
    self.receiver = receiver
    self.sitename = sitename


  def run(self):
    icmp_count = 0
    ping_result = ""
    packeloss_result = ""

    while not self.stopped:
       data = subprocess.Popen("ping -c1 "+str(sites[self.sitename]),shell = True,stdout=subprocess.PIPE)
       data.wait()
       time_manager[self.sitename][1] +=1 #counts the icmps sent 
       bufferdata = data.stdout.read() 
       ping_result = ms_pat.findall(bufferdata)
       packeloss_result = packetloss_pat.findall(bufferdata)

       if ping_result:
         ping_ms = ping_result[0][0]
       if packeloss_result:
         time_manager[self.sitename][2] +=1        
         ping_ms = "-1"

       ms_count[self.sitename].append(float(ping_ms))
       time.sleep(1)
       event = QCustomEvent(12345)
       event.setData(self.sitename+ping_ms)
       QApplication.postEvent(self.receiver, event)

  def stop(self):
    self.stopped = 1

我使用线程是因为有时我需要对不同的站点运行多个ping作业。在

我的问题是: 运行时,我得到了毫秒延迟的完美结果,但每隔几次ping我就得到一个不准确的结果,比实际应该的要高。在

我知道结果是不准确的,因为我同时在控制台上运行ping,而在那里我没有ping峰值

示例:

pingđms=20.0

pingđms=21.31

平逖ms=23.23

ping_ms=80.2

平逖ms=23.23

pingđms=24.2

我不明白为什么会这样。也许我需要用不同的方式编写代码。如果有人能帮助我,我将不胜感激。在

谢谢。在

我已经隔离了问题:

问题似乎不在代码中,而是在操作系统或ping命令本身。 当我每秒钟在控制台中手动运行命令:“ping-c1xxx.xxx.xxx.xxx“几次尝试后,我得到了相同的结果,一个奇怪的ping峰值。但是如果“乒”流利的“乒”xxx.xxx.xxx.xxx“,没有尖峰。在

是否可以从脚本中使用Popen运行fluent ping并读取结果?在


Tags: selfdata软件timedefmanagerresultping
2条回答

这看起来是一个很好的起点:

http://pypi.python.org/pypi/ping/0.1

当然,现在还不清楚你现在所做的是否真的有任何问题。由于ping时间是从ping的输出中解析出来的,所以我们不能将其归咎于进程生成开销之类的。在

尝试将close_fds=True添加到您的Popen呼叫中(参见讨论here)。如果在其他线程中打开了其他管道,则可能是它们以某种方式交互(强制执行线程的特定顺序)。考虑使用Popen.communicate(),而不是直接从进程的stdout流中读取。尽管如此,您的ping实现似乎不太可能根据其输出的缓冲程度返回不同的读数。在

在更高的层次上,您应该记住ping定时数据本质上是不可靠的。如果您无法修复峰值,并且确信它是来自Popen调用的伪制品(而不仅仅是随机噪声),那么对数据进行后期处理可能是合理的。例如,可以一次收集5个数据点,然后取中间值。(请注意,中位数对异常值的敏感性低于平均值)。这并不比ping已经在做的事情糟糕。在

更新26/02

很抱歉听到^没用。其他一些想法:

1.如果我们了解更多关于如何从shell运行ping的信息,可能会有所帮助。在python中,使用-c1ping限制为一次尝试。我猜,在shell中,您只需运行ping hostname并实时观察结果,这是真的吗?如果是,请尝试运行bash脚本,如下所示:

#! /bin/bash

for i in {1..50}
do
   ping -c1 somehostname
   # maybe 'sleep 1' here
done

仔细看看结果。峰值可能是您调用ping的结果。在

2.示例代码没有正则表达式定义。您是否百分之百确定他们从ping的输出中捕获了正确的值?在

相关问题 更多 >