From 344b052d3f30c3da9417d1f2df92c8e7ec24f884 Mon Sep 17 00:00:00 2001 From: ALLAOUA Rayen <rayen.allaoua8@etu.univ-lorraine.fr> Date: Tue, 30 Apr 2024 20:26:28 +0000 Subject: [PATCH] Add new file --- serverchatfin.py | 131 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 serverchatfin.py diff --git a/serverchatfin.py b/serverchatfin.py new file mode 100644 index 0000000..fc25d2c --- /dev/null +++ b/serverchatfin.py @@ -0,0 +1,131 @@ +import tkinter as tk # Importation de la bibliothèque tkinter pour créer une interface graphique +import socket # Importation de la bibliothèque socket pour la communication réseau +import threading # Importation de threading pour gérer les connexions concurrentes + +# Création de la fenêtre principale de l'interface graphique +window = tk.Tk() +window.title("Server") # Définition du titre de la fenêtre + +# Définition de l'adresse IP et du port du serveur +HOST = "127.0.0.1" +PORT = 8080 + +# Initialisation des variables pour le nom du client, la liste des clients et la liste des noms des clients +client_name = "" +clients = [] +client_names = [] + +# Fonction pour envoyer et recevoir des messages des clients +def send_recv_client_msg(client_connection, client_ip_addr): + global server, client_name, clients, clients_addr # Déclaration des variables globales utilisées dans la fonction + client_msg = "" # Initialisation du message du client + client_name = client_connection.recv(4096) # Réception du nom du client + client_name = client_name.decode("utf-8") # Décodage du nom du client + print(type(client_name)) + welcome_message = "Welcome/Azul/Bonjour " + client_name + ". Utilisez 'exit' pour quitter/ Use 'exit' to quit" # Message de bienvenue + client_connection.send(welcome_message.encode("utf-8")) # Envoi du message de bienvenue au client + client_names.append(client_name) # Ajout du nom du client à la liste des noms de clients + + # Mise à jour de l'affichage des noms de clients sur l'interface graphique + update_client_names_display(client_names) + + while True: + print("En attente de recevoir un message d'un client./Waiting to receive message from a client") + data = client_connection.recv(4096) # Réception des données du client + if not data: break # Sortir de la boucle si aucune donnée n'est reçue + if data == "exit": break # Sortir de la boucle si le client envoie "exit" + + client_msg = data.decode("utf-8") # Décodage des données du client + idx = get_client_index(clients, client_connection) # Obtention de l'indice du client dans la liste des clients + sending_client_name = client_names[idx] # Obtention du nom du client envoyant le message + + for client in clients: + if client != client_connection: + message_to_other_clients = sending_client_name + "->" + client_msg # Création du message à envoyer aux autres clients + client.send(message_to_other_clients.encode("utf-8")) # Envoi du message aux autres clients + + # Suppression du client de la liste + idx = get_client_index(clients, client_connection) + del client_names[idx] + del clients[idx] + client_connection.close() # Fermeture de la connexion avec le client + + # Mise à jour de l'affichage des noms de clients sur l'interface graphique + update_client_names_display(client_names) + +# Fonction pour obtenir l'indice d'un client dans la liste des clients +def get_client_index(client_list, curr_client): + for i in range(0, len(client_list)): + if client_list[i] == curr_client: + return i + return -1 + +# Fonction pour mettre à jour l'affichage des noms de clients sur l'interface graphique +def update_client_names_display(name_list): + tkDisplay.config(state=tk.NORMAL) # Activation de la zone de texte + tkDisplay.delete('1.0', tk.END) # Effacement de tout le texte précédent + for client in name_list: + tkDisplay.insert(tk.END, client+"\n") # Insertion des noms de clients dans la zone de texte + tkDisplay.config(state=tk.DISABLED) # Désactivation de la zone de texte + +# Fonction pour accepter les connexions des clients +def accept_clients(some_server): + print("Il faut passer à la fonction d'acceptation des clients./got to accept clients function") + while True: + client, addr = some_server.accept() # Acceptation de la connexion d'un client + print("Le serveur a accepté un client./Server accepted a client") + clients.append(client) # Ajout du client à la liste des clients + threading._start_new_thread(send_recv_client_msg, (client,addr),) # Démarrage d'un thread pour gérer la communication avec le client + +# Fonction pour démarrer le serveur +def start_server(): + startButton.config(state=tk.DISABLED) # Désactivation du bouton de démarrage + stopButton.config(state=tk.NORMAL) # Activation du bouton d'arrêt + + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Création du socket serveur + server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Configuration du socket + print("Socket serveur créé/Created server socket") + server.bind((HOST, PORT)) # Liaison du socket à l'adresse et au port spécifiés + server.listen(5) # Attente de connexions entrantes + print("Le serveur écoute/Server is listening") + threading._start_new_thread(accept_clients, (server,)) # Démarrage d'un thread pour accepter les connexions des clients + + hostLabel["text"] = "Host: " + HOST # Mise à jour du label d'adresse IP + portLabel["text"] = "Port: " + str(PORT) # Mise à jour du label de port + +# Fonction pour arrêter le serveur +def stop_server(): + stopButton.config(state=tk.DISABLED) # Désactivation du bouton d'arrêt + startButton.config(state=tk.NORMAL) # Activation du bouton de démarrage + +# Création de la partie supérieure de l'interface graphique avec les boutons de démarrage et d'arrêt du serveur +topFrame = tk.Frame(window) + +startButton = tk.Button(topFrame, text="Start", command=start_server) +startButton.pack(side=tk.LEFT) + +stopButton = tk.Button(topFrame, text="Stop", command=stop_server, state=tk.DISABLED) +stopButton.pack() +topFrame.pack(side=tk.TOP, pady=(5,0)) + +# Création de la partie centrale de l'interface graphique avec les labels d'adresse IP et de port +centerFrame = tk.Frame(window) +hostLabel = tk.Label(centerFrame, text="Host: x.x.x.x") +hostLabel.pack(side=tk.LEFT) +portLabel = tk.Label(centerFrame, text="Port: ####") +portLabel.pack() +centerFrame.pack(side=tk.TOP, pady=(5,0)) + +# Création de la partie inférieure de l'interface graphique pour afficher les noms des clients connectés +clientsFrame = tk.Frame(window) +clientsLabel = tk.Label(clientsFrame, text="Mini chat client-server en TCP") +clientsLabel.pack() # Ajout du label pour indiquer les clients connectés +scrollBar = tk.Scrollbar(clientsFrame) # Création d'une barre de défilement +scrollBar.pack(side=tk.RIGHT, fill=tk.Y) # Placement de la barre de défilement à droite +tkDisplay = tk.Text(clientsFrame, height=15, width=40) # Création d'une zone de texte pour afficher les noms des clients +tkDisplay.pack(side=tk.LEFT, fill=tk.Y, padx=(5,0)) # Placement de la zone de texte à gauche +scrollBar.config(command=tkDisplay.yview) # Configuration de la barre de défilement pour fonctionner avec la zone de texte +tkDisplay.config(yscrollcommand=scrollBar.set, background="#FFC0CB", highlightbackground="white", state="disabled") # Configuration de la zone de texte +clientsFrame.pack(side=tk.BOTTOM, pady=(5, 10)) # Placement du cadre des clients en bas de la fenêtre + +window.mainloop() # Lancement de la boucle principale pour exécuter l'interface graphique -- GitLab