diff --git a/Chat/clientUdp/clientUdp/ChatMessage.cs b/Chat/clientUdp/clientUdp/ChatMessage.cs index 0d37a840a04627065fd424ca6bf59d74ad9cadbd..27f548b8191482896718cd9871b5f52ead2b8a39 100644 --- a/Chat/clientUdp/clientUdp/ChatMessage.cs +++ b/Chat/clientUdp/clientUdp/ChatMessage.cs @@ -1,7 +1,4 @@ using System; -using System.Net; -using System.Net.Sockets; -using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; @@ -18,6 +15,7 @@ namespace ClientUdp class ChatMessage { public const int bufferSize = 1500; + public const int headerSize = 35; public Commande commande; // commande public CommandeType commandeType; // type (Requête/Réponse) @@ -45,16 +43,18 @@ namespace ClientUdp public byte[] GetBytes() { - byte[] buffer = new byte[bufferSize]; - buffer[0] = (byte)commande; - buffer[1] = (byte)commandeType; - Encoding.ASCII.GetBytes(pseudo, 0, pseudo.Length, buffer, 2); - byte[] intBuf = BitConverter.GetBytes(dataSize); - buffer[32] = intBuf[0]; + byte[] buffer = new byte[bufferSize]; // Déclaration du buffer + + buffer[0] = (byte)commande; // Commande + buffer[1] = (byte)commandeType; // Type de la commande + Encoding.ASCII.GetBytes(pseudo, 0, pseudo.Length, buffer, 2); // Pseudo à 30 bits + byte[] intBuf = BitConverter.GetBytes(dataSize); // Taille de la data + buffer[32] = intBuf[0]; // Int stocké sur 4bits buffer[33] = intBuf[1]; buffer[34] = intBuf[2]; buffer[35] = intBuf[3]; - Encoding.ASCII.GetBytes(data, 0, data.Length, buffer, 36); + Encoding.ASCII.GetBytes(data, 0, data.Length, buffer, 36); // Data + return buffer; } @@ -62,7 +62,6 @@ namespace ClientUdp { ChatMessage chatCommande = new ChatMessage(commande, type, data, pseudo); return chatCommande.GetBytes(); - //return GetBytes(commande, type, "serveur", data); } public override string ToString() diff --git a/Chat/clientUdp/clientUdp/ClientUdp.cs b/Chat/clientUdp/clientUdp/ClientUdp.cs index 3058e65928afbe6e9126da384f021ade6fe61210..fc604fe55b08fff2dbcd527c40652b1b8cfe7392 100644 --- a/Chat/clientUdp/clientUdp/ClientUdp.cs +++ b/Chat/clientUdp/clientUdp/ClientUdp.cs @@ -5,19 +5,67 @@ using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; namespace ClientUdp { class ClientUdp { + const int MsgsBufferSize = 100000000; + static string getPseudo() + { + String pseudo = String.Empty; + bool pseudoValide = true; + while (pseudoValide) + { + // Lecture pseudo au clavier + Console.Write("Pseudo : "); + pseudo = Console.ReadLine(); + if (pseudo.Length > 30) //on vérifie que le pseudo ne fasse pas plus de 30 caractères, taille fixe définie dans la classe ChatMessage + { + Console.WriteLine("Le pseudo est trop long"); + } + else + { + pseudoValide = false; + } + } + + return pseudo; + } + + static string getMessage() + { + + String msg = String.Empty; + bool messageValide = true; + while (messageValide) + { + // Lecture du message au clavier + Console.Write("Message : "); + msg = Console.ReadLine(); + if (msg.Length > ChatMessage.bufferSize - ChatMessage.headerSize) //on vérifie que le message ne dépassera pas la taille du buffer + { + Console.WriteLine("Le message est trop long"); + } + else + { + messageValide = false; + } + } + + return msg; + } + static void Main(string[] args) { try { //************************************************************** Initialisation - string serverIP = "130.79.81.200"; // A changer - int serverPort = 17021; // A changer + string serverIP = "127.0.0.1"; // A changer + int serverPort = 17021; // A changer + bool continuer = true; // Création de la socket d'écoute UDP Socket clientSocket = new Socket( @@ -29,34 +77,51 @@ namespace ClientUdp // Liaison de la socket au point de communication clientSocket.Bind(new IPEndPoint(IPAddress.Any,58600)); - // Création du EndPoint serveur EndPoint serverEP = new IPEndPoint(IPAddress.Parse(serverIP), serverPort); - - // Lecture message au clavier - Console.Write("Message : "); - String msg = Console.ReadLine(); - // Console.Write("Pseudo : "); - //String pseudo = Console.ReadLine(); - - ChatMessage chat_message = new ChatMessage(Commande.POST,CommandeType.REQUETE,msg,"fopalvens"); - //************************************************************** Communications - // Encodage du string dans un buffer de bytes en ASCII - //byte[] buffer = System.Text.Encoding.ASCII.GetBytes(msg); - byte [] buffer = chat_message.GetBytes();//transformation du tableau en byte - - Console.WriteLine("Taille buffer : " + buffer.Length); - - // Envoie du message au serveur - int nBytes = clientSocket.SendTo(buffer, 0, buffer.Length, SocketFlags.None, serverEP); - Console.WriteLine("Nouveau message envoye vers " - + serverEP - + " (" + nBytes + " octets)" - + ": \"" + msg + "\""); + // Création de la demande d'abonnement et du buffer associé + ChatMessage chat_subscribe = new ChatMessage(Commande.SUBSCRIBE, CommandeType.REQUETE, "", ""); + byte[] bufferSubscr = chat_subscribe.GetBytes(); + + // Envoi de la demande d'abonnement + clientSocket.SendTo(bufferSubscr, 0, bufferSubscr.Length, SocketFlags.None, serverEP); + + while (continuer) + { + // création du buffer qui va réceptionner la liste de messages + byte[] bufferGet = new byte[MsgsBufferSize]; + + //réception de la liste des messages + int nBytes = clientSocket.ReceiveFrom(bufferGet, bufferGet.Length, SocketFlags.None, ref serverEP); + //désérialisation de la chaîne comportant les messages avec pseudo + string messages = System.Text.Encoding.ASCII.GetString(bufferGet, 0, nBytes); + string[] listMessages = messages.Split('/'); + //affichage des messages + Console.WriteLine(""); + foreach (string mess in listMessages) + { + Console.WriteLine(mess); + } + + //appel de la fonction qui renvoie le pseudo lu au clavier avec les vérifications nécessaires + string pseudo = getPseudo(); + //appel de la fonction qui renvoie le message lu au clavier avec les vérifications nécessaires + string msg = getMessage(); + + //création du message en POST de type REQUETE avec le message entré au clavier plus le pseudo entré également au clavier + ChatMessage chat_message = new ChatMessage(Commande.POST, CommandeType.REQUETE, msg, pseudo); + + // Encodage string dans un buffer de bytes en ASCII + //transformation des messages en Bytes et placer dans les différents buffer + byte[] buffer = chat_message.GetBytes(); + + // Envoie du message POST au serveur + clientSocket.SendTo(buffer, 0, buffer.Length, SocketFlags.None, serverEP); + } //************************************************************** Conclusion diff --git a/Chat/serveurUdp/serveurUdp/ChatMessage.cs b/Chat/serveurUdp/serveurUdp/ChatMessage.cs new file mode 100644 index 0000000000000000000000000000000000000000..27f548b8191482896718cd9871b5f52ead2b8a39 --- /dev/null +++ b/Chat/serveurUdp/serveurUdp/ChatMessage.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClientUdp +{ + public enum Commande + { + POST, GET, HELP, QUIT, STOPSERVEUR, SUBSCRIBE, SUBSCRIBEv2, UNSUBSCRIBE + }; + + public enum CommandeType { REQUETE, REPONSE }; + + class ChatMessage + { + public const int bufferSize = 1500; + public const int headerSize = 35; + + public Commande commande; // commande + public CommandeType commandeType; // type (Requête/Réponse) + public int dataSize; // taille de la donnée + public String data; // données de la commande + public String pseudo; // pseudo de l'envoyeur + + public ChatMessage(Commande commande, CommandeType type, String data, String pseudo) + { + this.commande = commande; + this.commandeType = type; + this.dataSize = data.Length; + this.data = data; + this.pseudo = pseudo; + } + + public ChatMessage(byte[] buffer) + { + commande = (Commande)buffer[0]; + commandeType = (CommandeType)buffer[1]; + pseudo = Encoding.ASCII.GetString(buffer, 2, 30).TrimEnd(new char[] { '\0' }); + dataSize = BitConverter.ToInt32(buffer, 32); + data = Encoding.ASCII.GetString(buffer, 36, dataSize); + } + + public byte[] GetBytes() + { + byte[] buffer = new byte[bufferSize]; // Déclaration du buffer + + buffer[0] = (byte)commande; // Commande + buffer[1] = (byte)commandeType; // Type de la commande + Encoding.ASCII.GetBytes(pseudo, 0, pseudo.Length, buffer, 2); // Pseudo à 30 bits + byte[] intBuf = BitConverter.GetBytes(dataSize); // Taille de la data + buffer[32] = intBuf[0]; // Int stocké sur 4bits + buffer[33] = intBuf[1]; + buffer[34] = intBuf[2]; + buffer[35] = intBuf[3]; + Encoding.ASCII.GetBytes(data, 0, data.Length, buffer, 36); // Data + + return buffer; + } + + public static byte[] GetBytes(Commande commande, CommandeType type, String data, String pseudo) + { + ChatMessage chatCommande = new ChatMessage(commande, type, data, pseudo); + return chatCommande.GetBytes(); + } + + public override string ToString() + { + return "[" + commande + "," + commandeType + ",\"" + pseudo + "\"," + dataSize + ",\"" + data + "\"]"; + } + + } +} diff --git a/Chat/serveurUdp/serveurUdp/ServeurUdp.cs b/Chat/serveurUdp/serveurUdp/ServeurUdp.cs index cc7cb1432f541d447d435ce1dbeac39e87375310..6256ce5d7c343a42b80336a4f81266bade4a3b01 100644 --- a/Chat/serveurUdp/serveurUdp/ServeurUdp.cs +++ b/Chat/serveurUdp/serveurUdp/ServeurUdp.cs @@ -5,14 +5,58 @@ using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; +using ClientUdp; + namespace ServeurUdp { class ServeurUdp { - static void Main(string[] args) + static string messages = String.Empty; + static List<EndPoint> subscribers = new List<EndPoint>(); + + static void sendMsgs(Socket serverSocket, EndPoint clientEP) + { + // Pas de message sur le serveur on l'indique au client + if (messages == String.Empty) + { + byte[] buf = Encoding.ASCII.GetBytes("Il n'y a aucun message d'enregistré sur le serveur !"); + serverSocket.SendTo(buf, 0, buf.Length, SocketFlags.None, clientEP); + } + // Envoi des messages au client + else + { + byte[] buf = System.Text.Encoding.ASCII.GetBytes(messages); + serverSocket.SendTo(buf, 0, buf.Length, SocketFlags.None, clientEP); + } + Console.WriteLine("Liste des messages demandé !"); + } + + static void updateSubscribers(Socket serverSocket) + { + foreach(EndPoint ep in subscribers) + { + sendMsgs(serverSocket, ep); + } + } + + static bool isSubscriber(EndPoint ep) { + bool res = false; + for(int i = 0; i < subscribers.Count && !res;i++) + { + if (subscribers.ElementAt(i).ToString() == ep.ToString()) + { + res = true; + } + } + + return res; + } + + static void Main(string[] args) + { try { // ************************************************************** Initialisation @@ -27,28 +71,77 @@ namespace ServeurUdp // Liaison de la socket au point de communication serverSocket.Bind(new IPEndPoint(IPAddress.Any,17021)); + + bool continuer = true; //************************************************************** Communications - Console.WriteLine("Attente d'une nouveau message..."); + while (continuer) + { + Console.WriteLine("Attente d'un nouveau message..."); - // Reception message client - EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0); - byte[] buffer = new byte[80]; - int nBytes = serverSocket.ReceiveFrom(buffer, buffer.Length, SocketFlags.None, ref clientEP); + // Reception message client + EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0); + byte[] buffer = new byte[ChatMessage.bufferSize]; + serverSocket.ReceiveFrom(buffer, buffer.Length, SocketFlags.None, ref clientEP); - // Decodage du buffer de bytes en ASCII vers un string - String msg = System.Text.Encoding.ASCII.GetString(buffer, 0, nBytes); + // Message instancié à partir du buffer + ChatMessage msg = new ChatMessage(buffer); - Console.WriteLine("Nouveau message de " - + clientEP - + " (" + nBytes + " octets)" - + ": \"" + msg + "\""); + // Traitement par commande + switch(msg.commande) + { + // Si envoi de message + case Commande.POST: + messages += msg.pseudo + ':' + msg.data + '/'; + Console.WriteLine(msg.ToString()); + updateSubscribers(serverSocket); + break; + // Si demande des messages du serveur + case Commande.GET: + Console.WriteLine("Envoi des messages GET"); + sendMsgs(serverSocket, clientEP); + break; - //************************************************************** Conclusion + // Si demande d'abonnement aux messages + case Commande.SUBSCRIBE: + Console.WriteLine("Demande d'abonnement..."); + if (!isSubscriber(clientEP)) + { + Console.WriteLine("Un client s'est abonné"); + subscribers.Add(clientEP); + } + else + { + Console.WriteLine("Le client est déjà abonné"); + } + updateSubscribers(serverSocket); + break; + + // Si demande de désabonnement + case Commande.UNSUBSCRIBE: + Console.WriteLine("Demande de désabonnement..."); + if (isSubscriber(clientEP)) + { + Console.WriteLine("Un client s'est désabonné"); + subscribers.Remove(clientEP); + } + else + { + Console.WriteLine("Le client n'est pas abonné"); + } + break; + } + + + + + } // Fermeture socket Console.WriteLine("Fermeture Socket..."); serverSocket.Close(); + + //************************************************************** Conclusion } catch (SocketException E)