Westfall_T
Westfall_T

Reputation: 23

Sending multiple pings with Python

How can I ping 192.168.0.1 - 192.168.0.254 all at once? Trying to make the script run faster as it takes several minutes to finish.

import os
import subprocess


ip = raw_input("IP Address? ")
print "Scanning IP Address: " + ip

subnet = ip.split(".")

FNULL = open(os.devnull, 'w')

for x in range(1, 255):
    ip2 = subnet[0]+"."+ subnet[1] +"."+ subnet[2] +"."+ str(x)
    response=subprocess.Popen(["ping", "-c", "1", "-n", "-W", "2", ip2], stdout=FNULL, stderr=subprocess.STDOUT).wait()
if response == 0:
    print ip2, 'is up!'
else:
    print ip2, 'is down!'

Upvotes: 2

Views: 905

Answers (3)

Liam Kelly
Liam Kelly

Reputation: 3714

Or you could ping them all with one ping to the subnet broadcast address. So if your subnet is 255.255.255.0 (also known as /24) then just ping 192.168.0.255 and normally everyone will ping back.

Upvotes: 0

Pyonsuke
Pyonsuke

Reputation: 76

Look at the method you use to get a response:

response=subprocess.Popen(["ping", "-c", "1", "-n", "-W", "2", ip2], stdout=FNULL, stderr=subprocess.STDOUT).wait()

most importantly, the .wait() at the end means your program will wait until the process finishes.

You can start 255 processes at once (though you might want to start smaller chunks for the case of sanity) by putting the result of Popen (and not wait) into a list:

processes = []
for ip8 in range(1, 255):
    ip32 = subnet[0]+"."+ subnet[1] +"."+ subnet[2] +"."+ str(ip8)
    process = subprocess.Popen(["ping", "-c", "1", "-n", "-W", "2", ip32], stdout=FNULL, stderr=subprocess.STDOUT)
    processes.append(process)

You can then go through each and every process and wait until they finish:

for process, ip8 in zip(processes, range(1, 255)):
    ip32 = subnet[0]+"."+ subnet[1] +"."+ subnet[2] +"."+ str(ip8)
    response = process.wait()
    if response == 0:
        print("%s is up!" % (ip32))
    else:
        print("%s is down!" % (ip32))

Upvotes: 0

Kara
Kara

Reputation: 6226

Instead of waiting for each process to finish in your loop you can start all the processes at once and save them in a list:

processes = []

for x in range(1, 255):
    ip2 = subnet[0]+"."+ subnet[1] +"."+ subnet[2] +"."+ str(x)
    process = subprocess.Popen(["ping", "-c", "1", "-n", "-W", "2", ip2], stdout=FNULL, stderr=subprocess.STDOUT)
    processes.append((ip2, process))

Then you can then wait for each process to finish and print the results:

for ip2, process in processes:
    response = process.wait()
    if response == 0:
        print ip2, 'is up!'
    else:
        print ip2, 'is down!'

Upvotes: 2

Related Questions