Ping monitor - monitor ip in the background?

S

ScottZ

With python 2.6 and wxpython I'm trying to create a system tray icon
application based around an example found here:
http://codeboje.de/MailSneaker-Part-3-SystemTrayTaskBar-Icons-with-Python-and-wxPython/

The application will simply change the systray icon based on if an ip
address is online or not.

The ping portion looks like this:

if os.name == "nt": # Windows
pcmd = "ping -n 1 -w 1000 "
else: # *nix
pcmd = "ping -c1 -W1 "

def Ping(ipaddress):
# execute the code and pipe the result to a string
p = subprocess.Popen(pcmd + ipaddress, shell=True,
stdout=subprocess.PIPE)
# give it time to respond
p.wait()

a = re.search('(.*)ms', p.stdout.read())
if a:
return True
else:
return False

I've been able to add the ping check as a manual process (via a right
click menu item) but very confused on what direction to take on making
the ping a permanent loop while the app is running.

I was looking at making the ping routine a thread process but can't
figure out how to feed back the result to the calling app. Global
variable??

Ideas?
 
A

Andrey Balaguta

Hi, ScottZ.

I I have to write such a thing, I'll wrap the whole thing into some
class, say Pinger. It will have "do" method, which will perform one
particular pinging action. It'll also have a start/stop mechanism,
which will start a thread to continuously pinging a host. To notify
environment (say, yours tray icon) about host state change (dead/
alive), it will have callback mechanism (register_callback/
unregister_callback). Here, I've written a simple implementation,
maybe this will be helpful.

====== pinger.py ================
import os
import threading
import subprocess
import re
import time

class Pinger:
def __init__(self, ip = None):
self.ip = None
self.running = False
self.callbacks = list()
self.setAddress(ip)
def setAddress(self, ip):
if self.ip != ip:
if self.running:
self.stop()
self.ip = ip
def do(self):
if os.name == "nt": # Windows
pcmd = "ping -n 1 -w 1000 "
else: # *nix
pcmd = "ping -c1 -W1 "
p = subprocess.Popen(pcmd + self.ip, shell=True,
stdout=subprocess.PIPE)
# give it time to respond
p.wait()
a = re.search('(.*)ms', p.stdout.read())
if a:
return True
else:
return False
def start(self):
def run():
result = False
while self.running:
next = self.do()
if next != result and self.running:
[ callback(next) for callback in self.callbacks ]
result = next
self.ping_thread = threading.Thread(target = run)
self.running = True
self.ping_thread.start()
def stop(self):
self.running = False
def register_callback(self, callback):
if callback not in self.callbacks:
self.callbacks.append(callback)
def unregister_callback(self, callback):
if callback in self.callbacks:
self.callbacks.remove(callback)

if __name__ == '__main__':
p = Pinger('192.168.1.1')
def printout(alive):
if alive:
print 'Host is alive.'
else:
print 'Host is dead.'
p.register_callback(printout)
p.start()
while True:
print "Ding..."
time.sleep(1)

================

Note that printout will be called ONLY if host state has changed, not
on EVERY ping.
 
J

Jorgen Grahn

if os.name == "nt": # Windows
pcmd = "ping -n 1 -w 1000 "
else: # *nix
pcmd = "ping -c1 -W1 "

Not really correct. Unfortunately there are many variants of ping for
Unix, and they don't take the same flags. In Solaris, for example, -c
is not a count, and -W doesn't seem to exist at all.

If I recall correctly, you can't even count on Linux installations to
have compatible pings.

Too bad that you cannot easily implement ping in your program -- it
needs extra privileges in order to handle ICMP.

/Jorgen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,829
Latest member
PIXThurman

Latest Threads

Top