'Python Ping Servers

First time poster, long time reader. I'm hoping someone might be able to provide some insight into a python script that utilizes concurrent.futures (or some other concurrency method) for pinging a list of IPs. A lot of the solutions I've seen utilize IP ranges between 1-100 (but using the same first two to three octets ie 192.168.1.x) but are not inserting a list of real world IPs; that means I can't use those as I can't account for every single IP range as that's just excessive overhead.

I've had a bash at creating my own but I don't know if it actually is running concurrently (not very adept with Python) so any insight on either checking or making more efficient would be greatly appreciated. In a perfect world, I'd like to retain the ability to change how many pings the script sends.

###Ping List of Addresses###
start = time.perf_counter()

def ping_function(host):
    parameter = '-n' if platform.system().lower()=='windows' else '-c'

    command = ['ping', parameter, '1', host]
    return subprocess.call(command)==0

with concurrent.futures.ThreadPoolExecutor() as executor:
    result = executor.map(ping_function, IP)

print(tuple(result))

finish = time.perf_counter()
print(f'Pinging completed in {round(finish-start)} second(s)')

Any insight that could be provided would be absolutely unreal and would be hugely beneficial. The above code excerpt has the list inserted as "IP". The above code runs currently in 2 seconds but the list is quite short at 25 entries for a proof of concept. The list's datasource is from Sharepoint so the more items that are added, the larger the list will become and the longer the script will take to run.

Thanks in advance!!



Solution 1:[1]

ping on Windows does not set the exit code, so you can't use that to determine success. Instead, you have to look for clues in the output. A successful ping outputs 'TTL' to indicate the time-to-live value. This works for me. I capture the output of the command, and use the presence of the string 'TTL' to indicate success. It checks these 6 systems in 3 seconds:

import time
import subprocess
import concurrent.futures
from sys import platform

IP = [
    '192.168.192.10',
    '192.168.192.11',
    '192.168.192.12',
    '192.168.192.13',
    '192.168.192.14',
    '192.168.192.15'
]
start = time.perf_counter()

def ping_function(host):
    parameter = '-n' if platform=='win32' else '-c'
    command = ['ping', parameter, '1', host]
    try:
        output = subprocess.check_output(command)
        return b'TTL' in output
    except subprocess.CalledProcessError:
        return False

with concurrent.futures.ThreadPoolExecutor() as executor:
    result = executor.map(ping_function, IP)

print(tuple(result))

finish = time.perf_counter()
print(f'Pinging completed in {round(finish-start)} second(s)')

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1