Il peut être pratique de pinger tout un réseau pour connaître les adresses IP des machines disponibles, rapidement. Voici un petit script sans prétention qui permet de pinger tout un réseau en < 5 sec, contre + 300 sec avec la méthode « à l'ancienne ».

Voici un morceau de code Python 3.4+ fonctionnant sous GNU/Linux (facilement adaptable à Windows) :

#!/usr/bin/python3
""" Ping sous stéroïdes ! """

import asyncio
from asyncio.subprocess import PIPE
import ipaddress


async def ping(ip_addr):
    """ Pinger une adresse IP de manière asynchrone. """

    # Lancer la commande système `ping -c1 $IP` de manière asynchrone
    proc = await asyncio.create_subprocess_shell('ping -c1 ' + str(ip_addr),
                                                 stdin=PIPE,
                                                 stdout=PIPE,
                                                 stderr=PIPE)

    # Récupèrer le résultat, de manière asynchrone toujours
    ret = await proc.communicate()
    # Et décoder le tout
    ret = ret[0].decode('utf-8')

    # S'il n'y a pas d'erreur, affichage de l'adresse IP
    if '100% packet loss' not in ret:
        print(ip_addr)


async def get_live_hosts():
    """ Analyser tout un réseau de façon asynchrone. """

    # Demander à l'utilisateur le réseau à analyser
    # La syntaxe à utiliser : IP/masque
    # Exemples :
    #     192.168.0.0/24
    #     192.168.0.0/255.255.255.0
    network = input('Réseau [192.168.0.0/24] : ') or '192.168.0.0/24'

    # Récupération de toutes les adresses IP du réseau
    ip_addresses = ipaddress.ip_network(network).hosts()

    # Stockage des "ping" à faire dans une liste pour traitement ultérieur
    coros = []
    for ip_addr in ip_addresses:
        coros.append(ping(ip_addr))

    # Lancer toutes les coroutines en parallèle
    for routine in asyncio.as_completed(coros):
        await routine


def main():
    """ Point d'entrée du programme. """

    # Gestion des événements asynchrones
    loop = asyncio.get_event_loop()
    loop.run_until_complete(get_live_hosts())
    loop.close()

    return 0


if __name__ == '__main__':
    exit(main())

Exemple de sortie :

$ python3 ping.py
Réseau [192.168.0.0/24] :
192.168.0.10
192.168.0.11
192.168.0.12
192.168.0.254
192.168.0.48
192.168.0.36

Sources :

  1. Asynchronously receive output from long running shell commands with asyncio (Python 3.4+)?
  2. Python async/await Tutorial
  3.  Documentation Python : tasks and coroutines