Beruflich Dokumente
Kultur Dokumente
fr
Programmation C# - DotNet
Communication réseau
Les sockets sont un modèle permettant à des processus de communiquer entre eux. Leur rôle est
de faire communiquer aussi bien des processus s‛exécutant sur la même machine que des proces-
sus distants. Dans ce cas, la communication s‛établit à travers le réseau. Deux modes de commu-
nication sont possibles avec les sockets. Le mode connecté, qui utilise le protocole TCP, établit
une connexion entre la source et le destinataire. Avec ce dernier, on connaît en permanence la
destination des envois. Un système d‛accusé de réception et de contrôle d‛erreurs permet une
transmission fiable. Le mode non connecté utilise quant à lui le protocole UDP et ne crée pas de
connexion durable entre les deux processus. Lors de chaque envoi, il faut indiquer la destination.
Ce mode de communication ne propose pas d‛accusé de réception. Il est donc moins fiable que le
précédent mais reste plus simple. Les classes permettant d‛utiliser les sockets font partie de
l‛espace de noms System.Net.Sockets.
CRÉATION DE L‛APPLICATION
Pour que nous puissions nous concentrer sur l‛essentiel j‛ai préparé le formulaire et ses contrôles.
Vous le trouverez dans le sous dossier sources de l‛application.
● Copier le dossier client_et_serveur que vous trouverez dans le sous dossier sources dans votre
dossier de travail,
● Double cliquer sur le fichier client_et_serveur.sln pour démarrer la solution,
Ce formulaire est constitué de trois
onglets selon les actions à réaliser.
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 1
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
Et pour les réceptionner, nous devons disposer de la classe TcpListener. Ces deux classes sont
comprises dans l‛espace de noms System.Net. De même nous devons exploiter les sockets pour
surveiller les demandes de connexion. Les Sockets sont disponibles dans l‛espace de noms System.
Net.Sockets.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
//---RESEAU---
using System.Net;
using System.Net.Sockets;
//---THREAD pour qu’une connexion ne monopolise pas le processeur---
using System.Threading;
//---Accès aux fichiers séquentiels---
using System.Text;
Comme vous le constatez j‛ajoute de même une référence à l‛espace de noms System.Threading.
L‛écoute du réseau doit se faire dans un Thread pour ne pas risquer d‛emprunter toutes les res-
sources CPU. Enfin l‛espace de noms System.Text est inévitable puisque les informations transi-
tent par le réseau sous forme de tableaux de Bytes. Elles sont donc encodées. Et cet espace de
noms offre les méthodes permettant aussi bien d‛encoder que de décoder.
Si vous démarrez l‛application, vous constatez que le formulaire n‛apparaît pas à l‛écran mais en
sentinelle dans la barre des tâches. Je l‛ai en effet conçue pour qu‛elle s‛active à réception de
message ou par double clic sur l‛icône de la sentinelle. Cet événement est
donc déjà géré dans le code.
Nous avons ensuite besoin de variables publiques pour gérer les activités réseau. Nous allons donc
déclarer des variables concernant le client ainsi que le serveur.
Dans la classe com_reseau, à la suite des déclarations de tous les contrôles du formulaire et en
dehors de toute procédure,
● Commencer par déclarer toutes les variables concernant le client comme suit:
Seule la variable int port concerne à la fois le client et le serveur. Il s‛agit en fait du port de com-
munication pour les activités réseau.
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 2
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
...
private System.Windows.Forms.ListView m_r;
private System.Windows.Forms.ColumnHeader columnHeader4;
private System.Windows.Forms.ColumnHeader columnHeader5;
private System.Windows.Forms.ColumnHeader columnHeader6;
private System.Windows.Forms.NotifyIcon sentinelle;
private System.ComponentModel.IContainer components;
//===================================================================
//CONCERNE LE CLIENT...
//===================================================================
//==================================================================
//La classe TcpClient est bâtie sur Socket. Elle permet d’utiliser
//facilement ses capacités pour accéder aux services du protocole TCP.
//System.Net.Sockets
//==================================================================
TcpClient leClient = new TcpClient();
//==================================================================
//Le numéro de port (sortie) pour la communication est virtuel...
//Il est fonc choisi arbitrairement. Un numéro mal choisi peut
//occasionner des pbs de sécurité...Accès refusé !!
//==================================================================
private int port = 2564;
Tout d‛abord, je crée un objet TcpClient (leClient) que j‛utiliserai pour envoyer le flux de donner
via le réseau au destinataire sélectionné. Celui-ci devra être instancié à chaque nouvel envoi pour
signifier qu‛il s‛agit potentiellement d‛un nouveau client et couper le flux de transmission entre le
client et le destinataire (le serveur dans ce contexte).
Enfin la variable int port permet de déterminer un numéro de port (arbitraire) de communication
entre l‛expéditeur (le Client) et le destinataire (le Serveur).
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 3
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
Au même moment que j‛initialise les contrôles, je décide de réceptionner les informations de la
machine et de lancer directement le Thread d‛écoute du réseau. L‛application sera ainsi tout de
suite prête à recevoir les messages.
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 4
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 5
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 6
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
J‛instancie tout d‛abord l‛objet d‛écoute TcpListener sur le port d‛écoute choisi et défini en varia-
ble publique (jecoute = new TcpListener(port);). Je mets en marche le Socket (jecoute.Start();).
Ensuite j‛accepte le client si celui-ci se présente avec une demande de connexion (monSocket =
jecoute.AcceptSocket();). Et je réalise une boucle infinie (à l‛aide du booléen publique arretS) de
façon à scruter le réseau jusqu‛à réception du flux. Je prévois un tableau d‛octets pour le stockage
du flux (Byte[] transfert = new Byte[2048];). C‛est ainsi que les données transitent via le réseau.
La méthode Receive de l‛objet Socket permet de récupérer ces données. Je les stocke immédia-
tement dans le tableau d‛octets (transfert) précédemment déclaré. J‛exploite ensuite l‛espace de
noms System.Text pour décoder le flux (tableau de Bytes) et le mémoriser sous forme de texte
dans la variable donnees de type string.
Le test de l‛instruction if qui suit permet de s‛assurer que l‛écoute du flux ne se fait pas en boucle
dans le vide. Cette mésaventure se produit lorsque le client dont la connexion fut acceptée par
le serveur, se déconnecte. Si le message recomposé ne commence pas par la lettre ‘D‛ (je ferai
en sorte que tout message issu du client commence ainsi...), je coupe le flux en fermant l‛objet
TcpListener (ecoute) et en détruisant le thread d‛écoute pour le relancer aussitôt et rester dis-
ponible pour les autres connexions à venir.
if (donnees.Substring(0,1)!=»D»)
{
jecoute.Stop();
//Il faut détruire le thread et le relancer de manière à rétablir le
flux
//de transmission...
module_Serveur.Abort();
//Relance le Thread...
module_Serveur = new Thread(new ThreadStart(Ecoute));
module_Serveur.Start();
module_Serveur.Join(500);
//Et on ne poursuit pas le reste du code
return;
}
Dans le cas contraire, j‛ajoute les données recomposées (soit le message) dans le TreeView prévu
à cet effet. Pour ce faire, je détecte les différentes parties du message à l‛aide de la méthode in-
dexOf de la class string permettant de renvoyer la position de certains caractères particuliers.
int debut = 3;
int fin = donnees.IndexOf(«:»,0);
string de = donnees.Substring(debut, fin - 1);
string sujet = donnees.Substring(fin + 1);
construit_liste(m_r,de,sujet,System.DateTime.Now.ToString());
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 7
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
Lorsque l‛expéditeur et le sujet sont dissociés, j‛appelle la fonction construit_liste (à créer) qui se
charge de remplir les éléments et sous éléments du ListView. Cette fonction requiert en paramè-
tre, le nom de l‛objet ListView concerné, le string de l‛expéditeur, le string du sujet et le string
de la date.
Comme je fais en sorte que le client se déconnecte juste après avoir envoyé son message, pour
laisser la place à d‛autres messages, d‛autres clients, je coupe le flux de la même façon que précé-
demment pour le relancer aussitôt.
jecoute.Stop();
module_Serveur.Abort();
module_Serveur = new Thread(new ThreadStart(Ecoute));
module_Serveur.Start();
Ensuite, la console, tel un client, doit être en mesure d‛envoyer un message au destinataire choisi
dans la liste.
● Double cliquer sur le bouton Envoyer depuis le formulaire pour éditer son code,
● Et saisir sa ligne de code comme suit:
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 8
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
envoie_Serveur(m.Text);
Je fais appel à la fonction envoie_Serveur (non encore créée) qui doit se charger d‛établir la com-
munication et d‛envoyer le message encodé.
private void envoie_Serveur(string message)
{
try
{
string choix = liste_r.Text;
leClient = new TcpClient();
leClient.Connect(choix, port);
etat.Text = «Connexion en cours...»;
//=================================================================
//La transmission de données se fait via un objet NetworkStream qui
//s’obtient en utilisant la méthode GetStream...System.Net.Sockets
//=================================================================
NetworkStream transmission = leClient.GetStream();
message = ‘‘De ’’ + nom_Machine + ‘‘ (’’ + adresse_Ip.ToString() + ‘‘): ’’ + message;
Byte[] envoie = System.Text.Encoding.Default.GetBytes(message.ToCharArray());
transmission.Write(envoie,0,envoie.Length);
string de = nom_Machine + « (« + adresse_Ip.ToString() + «): «;
string sujet = m.Text;
construit_liste(m_e,de, sujet, System.DateTime.Now.ToString());
transmission.Close();
leClient.Close();
}
catch (Exception Ex)
{
gestion_Erreur(Ex);
}
}
Après avoir stocké le destinataire choisi par le biais de la liste déroulante, j‛instancie un nouvel
objet TcpClient. Le fait de recréer un objet TcpClient à chaque envoi permet de ne pas maintenir
le flux et de couper la connexion entre l‛expéditeur et le destinataire de façon à libérer le port
pour les potentielles autres connexions de clients. Ensuite j‛utilise la méthode Connect de l‛objet
TcpClient pour définir l‛expéditeur auquel je me connecte et le port de communication sollicité,
déclaré en variable publique. On crée l‛objet de flux (NetworkStream) en local et non en variable
publique de façon à pouvoir le couper instantanément après l‛envoi pour que l‛expéditeur (serveur)
reste disponible pour d‛autres connexions (d‛autres clients). Ensuite je stocke le message à en-
voyer sous forme de string dans la variable message. Puis je l‛encode sous forme de tableau de
Byte à l‛aide de l‛espace de noms System.Text.
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 9
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
Remarque: j‛utilise le système d‛encodage Default plutôt que ASCII de façon à retranscrire les
caractères latins (accentuations...). Ensuite j‛utilise la méthode Write de l‛objet NetworkStream
de façon à envoyer ces informations ainsi encodées à travers le réseau.
Ensuite, comme précédemment j‛appelle la fonction construit_liste(), pour remplir le ListView des
messages envoyés (Expéditeur, sujet et date...).
Ensuite je ferme le flux ainsi que le client pour libérer le port de communication une fois le mes-
sage envoyé (transmission.Close(); leClient.Close();).
En cas de souci (Catch), j‛appelle la procédure chargée de gérer les erreurs (gestion_
Erreur(Ex);).
Ici, je m‛arrête là pour simplifier le problème et surtout dissocier les fonctionnalités fondamenta-
les et je projette ensuite de faire évoluer l‛application en lui greffant ces fonctionnalités.
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 10
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.
DreamLive : www.dreamlive.fr
Programmation C# - DotNet
Communication réseau
Ces documents DreamLive sont libres de droits et ouverts à tous alors, profitez, partagez et
appréciez ! Pour nous retrouver sur le Web : http://www.dreamlive.fr.
Ces documents DreamLive sont libres de droits et ouverts à tous alors, Page 11
profitez, partagez et appréciez ! Pour nous retrouver sur le Web :
http://www.dreamlive.fr.