Partie 2 : Programmation réseau «de base» en C#
Plan du cours Généralités Communication Protocoles et serveurs associés Ip et port Client internet connecté Serveur internet connecté Protocole de communication en mode connecté Le mode non connecté Client / Serveur local
I Généralités Besoin de communiquer entre individus Proche l un de l autre (oral, écrit, ) Distant l un de l autre (oral, écrit, ) Transposition du problème à l informatique : on souhaite faire communiquer 2 processus P1 & P2 (locaux ou distants) entre eux. Comment faire passer de l info (autre que la signalisation)? 2 modèles d échange d information connus en «mode local» : 1. Lecteur / Rédacteur 2. Producteur / Consommateur Consommation de l information? Non Oui
Modèle Producteur / Consommateur Échange d information à sens unique : Producteur Consommateur Le producteur peut produire même si aucun consommateur (disponibilité du support) Le consommateur peut consommer même si le producteur n existe plus (persistance du support) Le producteur et le consommateur peuvent exister indépendamment Peu importe lequel commence Limitation : ne consommateur ne peut consommer plus de ressources que le producteur a produit (trivial) Chacun des processus peut jouer le rôle de producteur ou de consommateur au cours du temps C est l algorithme qui différencie le Producteur du Consommateur!
Modèle Client / Serveur (1) Consommation & limitation de la ressource ( comme dans Producteur / Consommateur) Forte distinction conceptuelle entre le Producteur (Serveur) et le Consommateur (Client) : Le serveur propose, à qui le souhaite, de communiquer avec lui et de lui fournir un service Le client décide de communiquer avec un serveur Le serveur : doit être lancé en premier ne prend pas la décision de se connecter à un client (attente) qui n existe peut être pas
Modèle Client / Serveur (2) C est toujours le client qui s adresse au serveur (qui peut refuser la demande de connexion) afin d «échanger des messages» : Interrogation du client, réponse du serveur (http, ftp, ) Interrogation du client, aucune réponse du serveur (Maj BD) Il arrive qu un serveur délivre un service à la simple connexion d un client (horloge parlante) Une fois le service délivré, le serveur attend le prochain client Même si le client délivre un service (applications réparties sur un réseau, ex : genome@home), il ne peut jouer le rôle de serveur : il communique uniquement avec le serveur. 2 processus ne peuvent jouer le rôle de client et de serveur à tour de rôle
Plan du cours Généralités Communication Protocoles et serveurs associés Ip et port Client internet connecté Serveur internet connecté Protocole de communication en mode connecté Le mode non connecté Client / Serveur local
Communication (1) Communication? Client Serveur Besoin d un support de communication (local (mémoire partagée) ou distant (réseau)) Le client doit identifier de la façon la plus précise possible, quel processus il souhaite atteindre sur le serveur Où est le serveur? Utilisation de IP comme protocole de la couche réseau Comment désigner le processus voulu? Par son nom? Pas valable car non unique Par son PID? Pas valable car change trop souvent
Communication (2) On a besoin d un identifiant unique, stable dans le temps et indépendant du SE utilisé pour caractériser le processus serveur Le service rendu est plus important que le processus qui le rend : svchost.exe (Service Host Process) : processus générique de Windows 2000/XP servant d'hôtes pour les autres processus dont le fonctionnement repose sur des bibliothèques dynamiques (DLLs). Il existe ainsi autant d'entrées svchost qu'il y a de processus qui l'utilisent. C est au serveur de demander (quand il le souhaite) l attribution de cette ressource. Une ressource crée (allouée) n a aucun sens s il n y aucun processus serveur associé à un service
Communication (3) «Ressources» P2? P1 Client Extérieur Intérieur Serveur On a besoin de faire communiquer simplement les processus clients et serveurs sans se soucier des couches basses Mise en place d une mémoire partagée si mode local Utilisation de protocoles (UDP, TCP, ICMP, ) si mode réseau
Communication (4) Création d un interface entre les différentes couches du modèle OSI : la couche application et la couche transport la couche application et la couche réseau Application Transport Réseaux UDP/TCP IP Interface Modèle OSI Cette interface doit permettre : La création d un service La connexion à un service L envois / la réception de message(s)
Communication (5) Plusieurs interfaces disponibles : STREAMS / TLI : System V Serveur Solaris (SUN) & Aix (IBM) Sockets : BSD date de 1983 dernière release : 1995 développé à Bercklet Serveur tout système (Unix, Unix like, Windows, ) Possibilité d utiliser d autres protocoles réseaux que TCP / IP comme AppleTalk, Xerox XNS, C est cette dernière interface que nous allons étudier!!
Plan du cours Généralités Communication Protocoles et serveurs associés Ip et port Client internet connecté Serveur internet connecté Protocole de communication en mode connecté Le mode non connecté Client / Serveur local
Protocole UDP (User Datagram Protocol) Client Serveur Question1 Réponse1 Question2 Réponse2 Question2 Réponse2 Pas de gestion des pertes de paquets Les paquets arrivent quand ils veulent (pas de notion d ordre) Duplication possible des paquets C est au processus client de gérer les erreurs Nombre de clients «illimités» Peu d influence de la couche IP Permet le broadcast et le multicast On parle de mode non connecté
Serveur itératif / UDP 1. Créer une socket et allouer une «ressource» connue des clients 2. Répéter : Lire une requête d un client Formuler la réponse Envoyer la réponse Serveur très simple Solution adaptée quand le volume d information à échanger est faible Ex : daytime, time,
Serveur concurrent / UDP Père : 1. Créer une socket et allouer une «ressource» connue des clients 2. Répéter : Lire une requête d un client Créer un fils pour élaborer la réponse Fils : Recevoir la demande du client Élaborer la réponse Envoyer la réponse au client Mourir Utilité si le traitement («Élaborer la réponse») est très long par rapport au temps mis pour créer un processus esclave Attention au nombre de fils créés avec cette méthode!
Protocole TCP (Transport Control Protocol) Client Serveur Question1 Réponse1 Question2 Réponse2 Réponse2 Établissement d un circuit virtuel bidirectionnel dédié à chaque client (1 socket / client) => pas de broadcast Trop de paquets émis lors de la connexion / déconnexion => gaspillage ressources Si le client est au repos / déconnecté, rien n indique au serveur sa présence / absence Facile à programmer Fiabilité de la transmission des données
Serveur itératif / TCP 1. Créer une socket et allouer une «ressource» connue des clients 2. Mettre la socket à l écoute (mode passif) 3. Accepter la connexion entrante, obtenir une nouvelle socket pour traiter la requête 4. Dialogue avec le client 5. Quand le dialogue est fini, fermer la connexion puis retour en 3 Type de serveur peu utilisé Met en jeu de faible volume d information avec nécessité d assurer le transport Temps de réponse doit être court Temps d établissement de la connexion non négligeable
Serveur concurrent / TCP Père : 1. Créer une socket et allouer une «ressource» connue des clients 2. Mettre la socket à l écoute (mode passif) 3. Répéter : Accepter la connexion entrante, obtenir une nouvelle socket pour traiter la requête Créer un fils pour traiter la réponse Fils : Recevoir la demande du client Mettre la socket à l écoute (mode passif) Dialogue avec le client Quand le dialogue est fini, fermer la connexion puis mourir Type de serveur le plus général Excellentes caractéristiques de transport et de souplesse d utilisation pour un client Usine à gaz pour des petits services
Plan du cours Généralités Communication Protocoles et serveurs associés IP et port Client internet connecté Serveur internet connecté Protocole de communication en mode connecté Le mode non connecté Client / Serveur local
Identification d un processus sur un réseaux Identification d un processus distant via un couple (nom_machine, nom_processus) Problème : ce ne sont pas des identifiants uniques Plusieurs machines peuvent avoir le même nom sur un réseau Plusieurs processus peuvent avoir le même nom sur la même machine Utilisation de l adresse IP d une machine comme identifiant unique pour son nom. On la représente par une suite de 4 octets : ex : 192.168.xxx.xxx (réseau local) 212.27.xxx.xxx (Internet) Utilisation d un identifiant unique pour le nom du processus (mais pas son PID car trop changeant) : le port. On le représente par un entier (4 octets).
Représentation d une adresse ip en C# Une adresse IP est une série de 4 nombres compris entre 0 et 255 séparés par le caractère. En C#, une adresse IP peut être représentée par une chaine de caractère il faut s assurer de sa validité : 1. En définissant nous même une fonction bool isipcorrect(string StrIp) { } string[] TabIp = StrIp.Split(new char[] {'.'}); if (4!= TabIp.Length) return false; foreach (string ip in TabIp) { int val; if (!Int32.TryParse (ip, out val) val > 255) return false; } return true; 2. En utilisant la classe Regex : Regex.IsMatch(StrIp, @"^\s*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s*$"); Attention, il faut inclure l espace de nom System.Text.RegularExpressions pour utiliser des objets de la classe Regex.
La classe IPAddress C est la classe par défaut pour représenter les adresses IP en C#. Elle est définie dans l espace de nom System.Net. Constructeur : public IPAddress ( byte[] address ) address : Valeur du tableau d'octets de l'adresse IP. Utlisation de la méthode TryParse() pour convertir un string en une IPAddress (C# 2.0) : public static bool TryParse ( string ipstring, out IPAddress address ) Une IPAddress peut être affiché à l écran car la méthode ToString() est surchargée pour cette classe.
IP DNS Utilisation de la classe Dns de l espace de nom System.Net. Pour connaître le DNS (Domain Name System) de la machine locale, on utilise la fonction GetHostName() de profil : public static string GetHostName () string MonPC = Dns.GetHostName(); Console.WriteLine(MonPC); //portdellalain Pour connaître les ips d une machine on utilise la fonction GetHostAddresses() de profil : public static IPAddress[] GetHostAddresses ( string hostnameoraddress )
IP DNS IPAddress[] tabip = Dns.GetHostAddresses(MonPC); foreach (IPAddress ip in tabip) Console.WriteLine(ip); //10.80.255.233 //139.124.187.43 Attention avec localhost tabip = Dns.GetHostAddresses("localhost"); foreach (IPAddress ip in tabip) Console.WriteLine(ip); // 127.0.0.1
IP DNS Utilisation d un objet de la classe IPHostEntry. La classe IPHostEntry associe un nom d'hôte DNS à un tableau d'alias et à un tableau d'adresses IP correspondantes. La classe IPHostEntry joue le rôle de classe d'assistance avec la classe Dns. Les données membres de cette classe sont : AddressList : liste d'adresses IP qui sont associées à un hôte. HostName : nom DNS de l'hôte. Aliases : liste d'alias qui sont associés à un hôte.
ip DNS Pour obtenir un objet de type IPHostEntry à partir d un objet de type IPAddress, on utilise la fonction GetHostEntry() de profil : public static IPHostEntry GetHostEntry ( IPAddress address ) Si on a une chaine de caractères, on utilise la même fonction surchargée pour les string : public static IPHostEntry GetHostEntry ( string hostnameoraddress ) IPHostEntry MonPC = Dns.GetHostEntry("portdellalain"); foreach (IPAddress ip in MonPC.AddressList) Console.WriteLine(ip); //10.80.255.233 //139.124.187.43
Notion de port Port Client Serveur @ IP Num port Service associé 7 Echo 21 Ftp 23 telnet 80 http 110 pop3 0 : port «jocker» [1,1023] : services de «bases» exécutés par root [1024, 49151] : services enregistrés [49152, 65535] : attribution dynamique pour les services privés /etc/services
Plan du cours Généralités Communication Protocoles et serveurs associés IP et port Client internet connecté Serveur internet connecté Protocole de communication en mode connecté Le mode non connecté Client / Serveur local
Client internet connecté L algorithme général d un client internet en mode connecté est le suivant : Création d un canal de communication Connexion au serveur Envoi(s) / réception(s) de message(s) Déconnexion du serveur Tous ces éléments se font grâce à la classe Socket de l espace de nom System.Net.Sockets.
Client internet connecté La spécifiaction du canal de communication se fait en construisant un objet de la classe Socket. Le constructeur est le suivant : public Socket ( AddressFamily addressfamily, SocketType sockettype, ProtocolType protocoltype ) Le champ AddressFamily spécifie la famille d adresse utilisée par la couche réseau : AppleTalk Adresse AppleTalk. InterNetwork Adresse IP version 4. InterNetworkV6 Adresse IP version 6. NetBios Adresse NetBios. Unix Adresse Unix locale vers hôte.
Client internet connecté Le champ SocketType spécifie le type de socket : Dgram : socket UDP Stream :socket TCP Raw : socket ICMP Le champ ProtocolType spécifie le protocole utilisé par la socket : Tcp Udp Icmp, IcmpV6 Dans notre cas : Socket Soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Attention à ne pas déclarer des chose incompatibles : SocketType.Stream & ProtocolType.Udp
Client internet connecté Pour se connecter à un serveur, il faut utiliser la fonction Connect() de profil : public void Connect ( IPAddress address, int port ) public void Connect ( string host, int port ) Soc.Connect("139.124.187.43", 60000); Pour fermer le canal de communication, on fait appel à la fonction Close() de profil : public void Close () Soc.Close();
Plan du cours Généralités Communication Protocoles et serveurs associés Ip et port Client internet connecté Serveur internet connecté Protocole de communication en mode connecté Le mode non connecté Client / Serveur local
Serveur internet connecté L algorithme général d un client internet en mode connecté est le suivant : Créer un canal de communication (SocCnx) Associer le canal de communication avec (IP, port) Attente d un client Créer un canal de communication dédié au client Envoi(s) / réception(s) de message(s) Fermer le canal de communication dédié au client Déconnecter le serveur
Serveur internet connecté On représente le couple (IP, port) grâce à un objet de type IPEndPoint. Le constructeur de cet objet est : public IPEndPoint ( IPAddress address, int port ) IPAddress ipserveur ; IPAddress.TryParse("139.124.187.43", out ipserveur); IPEndPoint MonServeur = new IPEndPoint(ipServeur, 60000) ; On utilise la fonction Bind() pour associer la Socket à un point de terminaison local (ici un IPEndPoint). SocCnx.Bind(MonServeur);
Serveur internet connecté On attend qu un client se connecte grâce à la fonction listen() de profil : public void Listen ( int backlog ) backlog : nombre de clients maximum dans la file d attente. SocCnx.Listen(10); On crée un canal de communication dédié entre le client et le serveur grâce à la fonction Accept() de profil : public Socket Accept () Socket SocClient = SocCnx.Accept(); Maintenant, le serveur parlera au client courant sur la socket SocClient.
Serveur internet connecté Une fois le service rendu, on ferme la socket dédiée au client grâce à la fonction Close(). SocClient.Close(); Une fois que le serveur n a plus de service à rendu, on ferme la socket de connexion en faisant appel à la fonction Close() : SocCnx.Close();
Plan du cours Généralités Communication Protocoles et serveurs associés Ip et port Client internet connecté Serveur internet connecté Protocole de communication en mode connecté Le mode non connecté Client / Serveur local
Communication en mode connecté Il faut qu un protocole de communication «standard» puisse être exécuté quelque soit le langage de programmation du client et/ou du serveur. Seuls les tableaux de caractères sont communs dans tous les langages. Il y a plusieurs formats pour les tableaux de caractères (ASCII, Unicode, ) On va être obligé de faire transiter des tableaux de bytessur la socket.
Communication en mode connecté Envoi de message se fait avec les fonctions send() de profil : public int Send ( byte[] buffer ) public int Send ( byte[] buffer, int size, SocketFlags socketflags ) Le champ SocketFlags peut prendre les valeurs suivantes : None : N'utiliser aucun indicateur pour cet appel. OutOfBand : Traiter les données hors bande. Peek : Lire le message entrant. Truncated : Le message était trop long pour pouvoir être contenu dans la mémoire tampon spécifiée et a été tronqué. Réception de message se fait avec les fonctions Receive() de profil : public int Receive ( byte[] buffer ) public int Receive ( byte[] buffer, int size, SocketFlags socketflags )
Communication en mode connecté Client echo en mode connecté string ChaineLue = Console.ReadLine(); byte[] msg = Encoding.UTF8.GetBytes(ChaineLue); Soc.Send(msg); byte[] TabByte = new byte[256]; Soc.Receive(TabByte); Console.WriteLine(Encoding.UTF8.GetString(TabByte)); Serveur echo en mode connecté byte[] TabByte = new byte[256]; SocClient.Receive(TabByte); SocClient.Send(TabByte);
Communication en mode connecté Si plusieurs messages arrivent les uns à la suite des autres, on ne peut pas les différencier. Solution : sacrifier un caractère qui sert de délimiteur entre chaque message. On aimerait envoyer autre chose que des tableaux de caractères sur la socket Pas possible, mais on peut transformer les types de base en tableaux de bytesgrâce à la classe BitConverter. Les principales fonctions membres de cette classe sont : public static byte[] GetBytes ( Type value ) public static Type ToType ( byte[] value, int startindex ) où Type est un type primitif
Communication en mode connecté Client echo en mode connecté (2) On fait précéder chaque chaine de caractères par son nombre d octet dans une représentation Unicode. string ChaineLue = Console.ReadLine(); Encoding Enc = Encoding.UTF8; byte[] NbByteAEnvoyer = BitConverter.GetBytes(Enc.GetByteCount(ChaineLue)); Soc.Send(NbByteAEnvoyer); byte[] msg = Enc.GetBytes (ChaineLue); Soc.Send(msg); byte[] BytesInt = new byte[sizeof(int32)]; Soc.Receive(BytesInt,4,SocketFlags.None); int NbByteALire = BitConverter.ToInt32(bytesInt,0); byte[] ChaineRecue = new byte[nbbytealire]; Soc.Receive(ChaineRecue); Console.WriteLine(Enc.GetString(ChaineRecue));
Serveur Sd = Socket() En résumé! Client Sd.Bind() sd = Socket() Sd.Listen() sdcom = Sd.Accept() Établissement de la connexion sdcom. Receive() Echanges sdcom.send() sd.connect() sd.send() sd. Receive() sdcom.close() Sd.Close() sd.close() Fermeture de la connexion Fermeture du serveur
Plan du cours Généralités Communication Protocoles et serveurs associés Ip et port Client internet connecté Serveur internet connecté Protocole de communication en mode connecté Le mode non connecté Client / Serveur local
Le mode non connecté L algorithme général d un client internet en mode non connecté est le suivant : Création d un canal de communication Envoi(s) / réception(s) de message(s) Déconnexion du serveur Il faut préciser que l on utilise des datagrammes lors de la création de la socket Socket Soc = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
Le mode non connecté L algorithme général d un serveur internet en mode non connecté est le suivant : Création d un canal de communication Associer le canal de communication avec (ip, port) Envoi(s) / réception(s) de message(s) Déconnexion du serveur
Le mode non connecté Il faut savoir à qui on envoie des données et qui nous les envoie pour préparer une réponse adéquate (tout le monde à accès au même canal de communication). L envoi de message se fait avec les fonctions SendTo() de profil : public int SendTo ( byte[] buffer, EndPoint remoteep ) public int SendTo ( byte[] buffer, SocketFlags socketflags, EndPoint remoteep ) La réception de messages se fait avec les fonctions ReceiveFrom() de profil : public int ReceiveFrom ( byte[] buffer, ref EndPoint remoteep ) public int ReceiveFrom ( byte[] buffer, SocketFlags socketflags, ref EndPoint remoteep ) Attention au passage par référence de l émetteur!!
Le mode non connecté Client Echo internet non connecté IPAddress ipserveur; IPAddress.TryParse(" 139.124.187.43 ", out ipserveur); IPEndPoint IPMonServeur = new IPEndPoint(ipServeur, 60001); string msg = Console.ReadLine(); Encoding Enc = UTF8Encoding.Unicode; byte[] tab = Enc.GetBytes(msg); Soc.SendTo(tab, IPMonServeur); byte[] rep = new byte[256]; EndPoint Serveur = (EndPoint) IPMonServeur; Soc.ReceiveFrom(rep, ref Serveur); Console.WriteLine(Enc.GetString(rep)); Soc.Close();
Le mode non connecté Serveur Echo internet non connecté IPAddress ipserveur; IPAddress.TryParse(" 139.124.187.43 ", out ipserveur); IPEndPoint IPMonServeur = new IPEndPoint(ipServeur, 60001); Soc.Bind(MonServeur); IPEndPoint IPClient = new IPEndPoint(IPAddress.Any,0); EndPoint Client = (EndPoint) IPClient; byte[] msg = new byte [256]; Soc.ReceiveFrom(msg, ref Client); Soc.SendTo(msg, Client); Soc.Close();
Serveur Sd = Socket() En résumé! Client Sd = Socket() Sd.Bind() Sd.Connect() Non nécessaire Sd.ReceiveFrom() Echanges Sd.SendTo() Sd.SendTo() Sd.ReceiveFrom() Sd.Close() Sd.Close()
Plan du cours Généralités Communication Protocoles et serveurs associés Ip et port Client internet connecté Serveur internet connecté Protocole de communication en mode connecté Le mode non connecté Client / Serveur local
Client / Serveur local Pour créer un client / serveur local (connecté ou non), nous avons 2 possibilités : 1. Déclarer le champ AddressFamily de la socket de type Unix. Mais on ne peut plus utiliser ce qu on a vu précédemment car la zone d échange est un fichier! 2. Utiliser localhost (ip : 127.0.0.1) comme adresse ip locale. Dans ce cas, ce que nous avons vu précédemment marche toujours.