Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过Popen帮助ping_Python_Linux_Multithreading_Popen_Ping - Fatal编程技术网

Python 通过Popen帮助ping

Python 通过Popen帮助ping,python,linux,multithreading,popen,ping,Python,Linux,Multithreading,Popen,Ping,我正在开发一个软件来监控不同地点的通讯。 原理很简单:每秒发送ping并实时显示结果(毫秒延迟、丢包等) 还有一点很重要,我是从Linux运行软件的,所以为了从我的软件ping,我选择subprocess.Popen方式,因为打开套接字需要以root用户身份登录。我不想让每个人都有根用户访问服务器的权限 以下是ping的类责任: class WorkerThread(QThread): def __init__(self,receiver,sitename): QThread._

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

还有一点很重要,我是从Linux运行软件的,所以为了从我的软件ping,我选择subprocess.Popen方式,因为打开套接字需要以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作业

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

我知道结果并不准确,因为我同时在控制台上运行ping,但在那里我没有得到ping峰值

例如:

ping_ms=20.0

ping_ms=21.31

ping_ms=23.23

ping_ms=80.2

ping_ms=23.23

ping_ms=24.2

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

谢谢

我已经隔离了问题:

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


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

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


当然,你现在所做的事情是否真的有问题还不清楚。由于ping时间是从ping的输出中解析出来的,因此我们不能将其归咎于进程生成开销或其他原因。

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

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

更新26/02

很遗憾,我没能帮上忙。还有一些其他想法:

1。如果我们能从shell中进一步了解您如何运行
ping
,可能会有所帮助。在python中,使用
-c1
ping
限制为一次尝试。我猜,在shell中,您只需运行
ping hostname
并实时查看结果——这是真的吗?如果是,请尝试运行bash脚本,如下所示:

#! /bin/bash

for i in {1..50}
do
   ping -c1 somehostname
   # maybe 'sleep 1' here
done
仔细观察结果。这些尖峰可能是您调用
ping
的方式造成的


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

为什么您认为延迟峰值不准确?在您和主机之间可能会有大量的延迟点。因为我同时从控制台运行ping,而在那里我没有得到pingspike@Urban48,这对我来说似乎不是很有说服力;我看不出为什么两次ping(即使它们几乎同时发生)必然会产生相同的结果。是的,控制台上的ping非常稳定,没有一个尖峰,而脚本每隔几秒钟就给我一个尖峰。差异非常明显。您是否尝试过在没有shell=True的情况下使用此选项?e、 例如:data=subprocess.Popen([“/bin/ping”、“-c1”、“+str(sites[self.sitename])),stdout=subprocess.PIPE)tnx为您解答。使用open sockets方法比popen更有效。似乎我没有收到ping尖峰。但我尝试避免这种情况。将根赋予python脚本不是很明智。我关于setuid的评论不正确,因此我将其删除。要真正使python脚本以根运行,您还必须将python解释器设置为uid这是个糟糕的主意。对不起:-(谢谢你的回答,close_fds=True,没有帮助。这很奇怪。如果我运行多个ping作业,有时它们都会同时得到这个峰值,有时只是其中的一部分。但是每隔几秒钟就会发生一次。峰值很大:从20毫秒延迟到140毫秒。我考虑过你提供的后期处理,但我需要显示我的结果尽可能实时。因此,我想打开套接字并发送pings手册是一个不错的选择,但在Linux中有点问题。更新了答案,添加了一些额外的想法,可能会帮助您了解问题的真相。祝您好运!您的第一个建议明确指出问题不在代码中!我尝试了您建议的方法h bash脚本,我得到了相同的ping尖峰,这意味着问题在于操作系统或ping命令本身。当ping流畅时,它的尖峰是自由的,当ping与-c或-w一起使用时,我得到了ping尖峰。我该如何处理它?我很高兴听到您能够隔离问题。我建议如下:使用
-c2
运行ping。然后从e在以下情况下的产出: