Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème d'envoie de fichier via socket

Problème d'envoie\reception de fichier via socket

    30 juillet 2023 à 19:22:18

    Bonjour à tous, j'essaye depuis quelques temps de crée un petit jeu qui est un système de déverrouillage "protégé" en Python. Il comprend un serveur, un programme 'Terminal' avec une interface graphique, et cinq fichiers clés. L'utilisateur doit insérer les cinq clés en utilisant les fichiers clés, chaque fichier étant à usage unique. Chaque fois qu'une clé est insérée, la valeur 'key' du programme 'Terminal' est mise à jour. Une fois que 'key' atteint 5, l'utilisateur peut cliquer sur le bouton 'Unlock' du programme 'Terminal' pour envoyer une verification du nombre de clé au serveur. Si le nombre est correct, le serveur renvoie un fichier "protégé". 

    Le serveur est stocké dans une VM connecté directement au réseau

    Le terminal peut être exécuté de n'importe quel appareil

    Le problème c'est que lorsque je tente d'appuyer sur le bouton "unlock" de mon terminal, le fichier "terminal" freeze et je ne recois pas le "fichier protégé". J'ai tenter de debogguer mon code et le problème semble venir de mon terminal.py. 

    PS : J'ai remplacé les addresse ip et le port par des "x", le problème de vient pas de la ne vous inquitez pas ;)

    Voici mon terminal.py


    import tkinter as tk
    import socket
    import threading
    import time
    
    def unlock():
        global key, server_running
        if key == 5:
            response = send_request(str(key))
            if response == "SEND_FILE":
                receive_file()
                print("log4")
                display_response("Fichier protégé reçu avec succès !")
            else:
                display_response(response)
            # Après avoir obtenu la réponse du serveur, mettre à jour la variable pour indiquer que le serveur est arrêté
            server_running = False
    
        else:
            display_response("Clés insuffisantes pour déverrouiller le fichier.")
    
    def send_request(data):
        try:
            client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client_socket.connect(('x.x.x.x', xxxxx))
            client_socket.send(data.encode())
            response = client_socket.recv(1024).decode()
            client_socket.close()
            return response
        except ConnectionRefusedError:
            return "Le serveur n'est pas disponible."
    
    def display_response(response):
        response_label.config(text=response)
    
    def update_key():
        global key, server_running
        while server_running:
            with open('key.data', 'r') as key_file:
                key = int(key_file.read().strip())
            key_label.config(text="Clé: " + str(key))
            time.sleep(1)  # Attendre 1 seconde avant de mettre à jour à nouveau la clé
    
    
    def receive_file():
        print('[Client] Connexion au serveur')
        s = socket.socket()
    
        try:
            s.connect(("x.x.x.x", xxxxx))
    
            print('[Client] Réception des données')
    
            with open("fichier_recu.txt", "wb") as f:
                while True:
                    data = s.recv(1024)
                    if not data:
                        break
                    f.write(data)
    
            print('[Client] Fichier reçu')
    
        except Exception as e:
            print('[Client] Erreur de connexion :', e)
    
        finally:
            print('[Client] Fermeture socket')
            s.close()
    
            print('[Client] Fermeture fichier')
            f.close()
    
    
    root = tk.Tk()
    root.title("Terminal")
    
    unlock_button = tk.Button(root, text="Unlock", command=unlock)
    unlock_button.pack(pady=10)
    
    key_label = tk.Label(root, text="Clé: 0")
    key_label.pack(pady=5)
    
    response_label = tk.Label(root, text="")
    response_label.pack(pady=10)
    
    # Créer le fichier key.data pour stocker la valeur de 'key'
    with open('key.data', 'w') as key_file:
        key_file.write('0')
    
    # Verrou pour accéder au fichier key.data
    lock = threading.Lock()
    
    # Variable pour indiquer si le serveur est en cours d'exécution ou arrêté
    server_running = True
    
    # Créer un thread pour mettre à jour la variable 'key' depuis le fichier key.data
    update_thread = threading.Thread(target=update_key)
    update_thread.start()
    
    root.mainloop()
    

    Voici mon server.py

    import socket
    import threading
    
    host = 'x.x.x.x'
    port = xxxxx
    
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))
    server_socket.listen()
    
    
    def handle_client(client_socket):
        request = client_socket.recv(1024).decode()
    
        if request == '5':
            print('[Server] Clé validée, envoi du fichier')
            client_socket.send('SEND_FILE'.encode())
            try:
                send_file(client_socket)
            except Exception as e:
                print('[Server] Erreur lors de l\'envoi:', e)
    
        else:
            client_socket.send('Clé incorrecte'.encode())
    
        client_socket.close()
    
    
    def send_file(client_socket):
        print('[Server] Ouverture du fichier')
    
        try:
            with open("fichier.txt", 'rb') as f:
    
                print('[Server] Lecture par morceaux')
                data = f.read(1024)
                while data:
                    print('[Server] Envoi des données')
                    client_socket.send(data)
                    data = f.read(1024)
    
            print('[Server] Fichier envoyé')
    
        except Exception as e:
            print('[Server] Erreur de lecture/envoi:', e)
    
        finally:
            print('[Server] Fermeture socket')
            client_socket.close()
    
        print('[Server] Fermeture fichier')
        f.close()
    
    
    while True:
        client_socket, address = server_socket.accept()
    
        print('[Server] Client connecté, adresse:', address)
    
        client_thread = threading.Thread(target=handle_client, args=(client_socket,))
        client_thread.start()
    
    print('[Server] Serveur démarré, en attente de connexions...')

    Voici le code de l'un de mes fichiers clé : 

    import os
    import time
    
    def insert_key():
        with open('key.data', 'r') as key_file:
            key = int(key_file.read().strip())
        with open('key.data', 'w') as key_file:
            key_file.write(str(key + 1))
    
    if __name__ == "__main__":
        insert_key()
        time.sleep(1)  # Attente de 1 seconde pour s'assurer que le programme se termine
        os.remove(__file__)  # Supprimer le fichier clé
    


    Merci à tous ceux qui pourront m'aider

    • Partager sur Facebook
    • Partager sur Twitter
      31 juillet 2023 à 9:35:10

      Commencez par faire fonctionner votre code avec client et serveur sur la même machine (ce sera plus simple)... et simplifiez: une interface utilisateur console est largement suffisante pour tester la partie réseau. Lorsqu'elle fonctionne, l'habiller avec un GUI plus convivial pourquoi pas... Mais alors vous saurez que le côté réseau fonctionne avant d'ajouter des complications dans votre code.

      Après  côté mise au point, l'affichage de messages avec des print pour conforter que le code se déroule bien comme attendu... c'est le boulot de base.

      note: les sockets récupèrent et expédient des bytes et non des str. Le serveur n'a pas pu expédier 'SEND FILE' (ça devrait planter) et le client attend de recevoir quelque chose. En attendant, l'interface est bloquée: normal.

      -
      Edité par mps 1 août 2023 à 11:06:04

      • Partager sur Facebook
      • Partager sur Twitter

      Problème d'envoie de fichier via socket

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown