Rédiger un rapport en python

codeur782 -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,
Je developpe une application serveur/client en python et j'aimerais que le serveur rédige un rapport de chaque interaction avec les clients dans un fichier texte.

Voici mon code :

f = open("rapport_srv.txt","w")

def accept_loop():
    while True:
        my_socket.listen()
        client, adresse = my_socket.accept()
        broadcast_list.append(client)
        start_listenning_thread(client)
        print("Nouveau client avec l'IP {0} sur le port 8000".format(adresse[0]))
        f.write("Nouveau client avec l'IP {0} sur le port 8000".format(adresse[0]))
        f.write("\n")
        print("Date et heure de connexion :", str(time))
        f.write("Date et heure de connexion : "+datetime.now().strftime("%d/%m/%y %H:%M:%S"))
        f.close()


En premier lieu, je demande au programme de créer un fichier texte
rapport_srv.txt
, puis dans la boucle j'écris dans ce fichier chaque événement.

J'ai deux soucis :
  • lorsque j'éteins le serveur et que je le rallume, le fichier texte se vide et repart de zéro.
  • lorsque un seul client se connecte, le programme écrit bien les informations, mais quand un deuxième client se connecte le serveur indique une erreur :


Traceback (most recent call last):
  File "/root/serveur.py", line 55, in <module>
    accept_loop()
  File "/root/serveur.py", line 24, in accept_loop
    f.write("Nouveau client avec l'IP {0} sur le port 8000".format(adresse[0]))
ValueError: I/O operation on closed file.


(je suis sous kali linux)

merci de votre aide, cordialement.

Message modifié par la modération
Pour une lecture plus facile du code, à l'avenir utilisez les balises, VOIR CETTE PAGE

3 réponses

  1. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     
    Bonjour,

    "ValueError: I/O operation on closed file." opération d'entrée/sortie sur un fichier fermé

    Dans ta boucle while, tu fermes le fichier à la fin du 1er tour, ( f.close() )donc au 2eme tour, impossible d'écrire dedans ...
    0
  2. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    Bonjour,

    Pour écrire à la suite d'un fichier, il faut l'ouvrir en mode append ('a') et non write ('w').

    Pour fermer un fichier au bon moment (seulement s'il a été ouvert avec succès, et y compris si une exception est levée), je t'invite à utiliser un context manager (i.e. utiliser
    with
    ) qui s'occupera de faire
    f.close()
    . Il devrait d'ailleurs en être de même pour n'importe quel descripteur de fichier ce qui inclue les sockets.

    Si on repart de ce tutoriel :

    client.py

    #!/usr/bin/env python3
    
    import socket
    
    HOST = '127.0.0.1'  # The server's hostname or IP address
    PORT = 65432        # The port used by the server
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((HOST, PORT))
        s.sendall(b'Hello, world')
        data = s.recv(1024)
    
    print('Received', repr(data))


    server.py

    #!/usr/bin/env python3
    
    import datetime, socket
    
    HOST = '127.0.0.1'  # Standard loopback interface address (localhost)
    PORT = 65432        # Port to listen on (non-privileged ports are > 1023)
    
    def message(s, f=None):
        print(s)
        if f:
            print(s, file=f)
    
    filename = "toto.log"
    with open(filename, "a") as f:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.bind((HOST, PORT))
            s.listen()
            conn, addr = s.accept()
            with conn:
                print('Connected by', addr)
                message(f"Nouveau client avec l'IP {addr[0]} sur le port {PORT}", f)
                message(f"Date et heure de connexion : {datetime.datetime.now().strftime('%d/%m/%y %H:%M:%S')}", f)
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    conn.sendall(data)


    Par ailleurs, je pense que ce que tu veux faire, tu devrais jeter un œil au module
    logging
    qui me paraît bien plus approprié que de le recoder, surtout si tu envisages d'utiliser des threads. Dans ce cas, il est important que ton logger soit robuste aux accès concurrents.

    Bonne chance
    0