2022/10/30

Envoyer et recevoir des données sur le réseau en Python

En quelques minutes avec Python, Debian 11.5 et nmap, on peut écrire un programme qui permet d'envoyer des données entre deux ordinateurs.

Quelques limites:

1. Il faut changer la constante RESEAU pour correspondre à so réseau local. La commande ip a est utile pour déterminer son adresse IP et son masque réseau.

2. Il faut que les deux machines soient sur le même réseau local pour se parler.

3. Il faut que les machines soient visibles par nmap. Normalement, que le ping fonctionne.

# Il faut installer nmap et pip avec apt-get install nmap python3-pip.
# Ensuite, il faut pip install python-nmap.
# Mieux vaut redémarrer le terminal après avoir installé les applications précédentes.
import nmap
import socket
RESEAU = "172.22.140.0/20"
def trouver_ordinateur() :
    print(
        "Découverte des ordinateurs sur le réseau. "
        "Ceci peut prendre quelques secondes..."
    )
    nm = nmap.PortScanner()
    nm.scan(hosts=RESEAU, arguments="-n -sP -PE -PA21,23,80,3389")
    ordre = 0
    ordinateurs = nm.all_hosts()
    for ordinateur in ordinateurs:
        print(f"{ordre} - {ordinateur}")
        ordre += 1
    choix = int(input("Entrer un  numéro: "))
    ordinateur = ordinateurs[choix]
    print(f"Ordinateur {ordinateur} choisi.")
    return ordinateur
def connecter(mode):
    port = int(input("Entrer port (2000 à 65535): "))
    socket_1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    canal_1 = (trouver_ordinateur(), port)
    canal_2 = (trouver_ordinateur(), port + 1)
    socket_2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    if mode == 1:
        socket_1.bind(canal_1)
        # J'ignore l'addresse avec _.
        donnees, _ = socket_1.recvfrom(4096)
        print(f"< {donnees.decode('utf-8')}")
    else:
        echange = socket_1
        socket_1 = socket_2 
        socket_2 = echange
        echange = canal_1
        canal_1 = canal_2
        canal_2 = echange
        socket_1.bind(canal_1)
    print("Ctrl+C pour arrêter le serveur...")
    while True:
        a_envoyer = input("> ")
        if a_envoyer == "disparaître":
            break
        socket_2.sendto(a_envoyer.encode('utf-8'), canal_2)
        # J'ignore l'addresse avec _.
        donnees, _ = socket_1.recvfrom(4096)
        print(f"< {donnees.decode('utf-8')}")
    socket_1.close()
    socket_2.close()
if __name__ == "__main__":
    mode = int(input(
        "Choisir le mode (1. écouter avant de la parler, "
        "2. parler avant d'écouter): "
    ))
    connecter(mode)

Pourquoi avoir deux sockets? Pour pouvoir communiquer sur le même ordinateur en ouvrant deux terminaux et où le premier terminal fonctionnera en mode 1 et le second en mode 2.

J'ai fait quelques changements au code d'origine en écrivant ce message. Si ça plante, c'est potentiellement à cause de ça. Ça devrait être assez simple à corriger. Le code est court.

Aucun commentaire:

Publier un commentaire