How to Ping Multiple Addresses Asynchronously Part I

by: George El., February 2019, Reading time: 2 minutes

In this post, I will show you how to ping many ip addresses synchronously, or asynchronously using threads. the following examples work only with python 3.

First I will use a list comprehension to create a list of ip addresses

ips = ["192.168.2.{}".format(i) for i in range(1,11)]

the above code will create addresses 192.168.2.1 - 10

Now all I have to do is loop through the list and call the function that will do the ping

for ip in ips:
    ping(ip)

I will create the function that will ping each ip address. The function will take one argument, the ip address.

def ping(ip):
    ping_reply = subprocess.run(["ping","-n","2", ip])

This will work on windows. On unix, replace -n with -c. -c is the the count and I use 2 packets, because the first ping can fail if the mac is not resolved. If you want to supress the output you can use.

def ping(ip):
    ping_reply = subprocess.run(["ping","-n","2", ip],stderr=subprocess.PIPE, stdout=subprocess.PIPE)

the reply has a returncode that shows if it failed or succeeded

  • 0 is success
  • 1 is failure

However, if the network is unreachable, it also returns 0, so I have to check this out and modify the result accordingly.

def ping(ip):
    ping_reply = subprocess.run(["ping","-n","2", ip],stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    result =""
    if ping_reply.returncode == 0:
        if ("unreachable" in str(ping_reply.stdout)):
            result = ("\n* No response from device %s" % ip)
        else:
            result= ("\n* OK response from device %s" % ip)
    elif ping_reply.returncode == 1:
        result= ("\n* No response from device %s" % ip)
    return result

The whole code will look like this:

import subprocess

ips = ["192.168.2.{}".format(i) for i in range(1,10)]

def ping(ip):
    ping_reply = subprocess.run(["ping","-n","2", ip],stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    result =""
    print (".", end='')
    if ping_reply.returncode == 0:
        #ping will return 0 success if destination is unreachable so I have to check this
        if ("unreachable" in str(ping_reply.stdout)):
            result = ("\n* No response from device %s" % ip)
        else:
            result= ("\n* OK response from device %s" % ip)
    elif ping_reply.returncode == 1:
        result= ("\n* No response from device %s" % ip)
    return result

for ip in ips:
    print(ping(ip))

Now if you have to ping a lot of ip addresses and a lot of them do not respond, this will take a long time. So you have to use threads, or even better a thread pool. In Part II I will show you how to do this.

comments powered by Disqus