Skip Navigation Links
Accueil
Java Standard EditionExpand Java Standard Edition
Java EE 5Expand Java EE 5
Visual Basic .Net 2005Expand Visual Basic .Net 2005
Visual C++ .Net 2005Expand Visual C++ .Net 2005
Visual C# .Net 2005Expand Visual C# .Net 2005
Cours ASP .Net 2.0Expand Cours ASP .Net 2.0
PostgresqlExpand Postgresql
LinuxExpand Linux
Visual Studio 2008Expand Visual Studio 2008
ASP 3.0 ClassiqueExpand ASP 3.0 Classique
Cours Javascript - DOM - DHTMLExpand Cours Javascript - DOM - DHTML
Cours AjaxExpand Cours Ajax
VBAExpand VBA
AssembleurExpand Assembleur
PerlExpand Perl
MembresExpand Membres
L'auteur du site
Nouveautés sur le site
Contacts
Plan du site
Accueil > Visual C# .Net 2005 > V Communication Tcp avec TcpClient et TcpListener
____________________________________________________________________________________________________
Connexion

V) COMMUNICATION TCP AVEC TCPCLIENT ET TCPLISTENER

V.I) La classe TcpClient

V.II) La classe TcpListener

V.III) Source d'exemple communication Tcp avec TcpClient et TcpListener

 

Ce cours est largement inspiré de MSDN. Merci donc à eux pour leurs explications claires à ce sujet.

Le .net framework fournit une manière de communiquer directement en TCP, sans forcément passer par des sockets. Il s’agit donc d’une méthode un peu moins bas niveau que les sockets, mais qui reste un équivalent des sockets. Il s’agit des classes TcpClient et TcpListener. Ces classes peuvent être remplacées chacune par la classe Socket( System.Net.Sockets), et peuvent être utilisées en même temps que la classe Socket( par exemple un TcpListener et un Socket en client, ou bien un Socket en écouteur et un TcpClient en client).

V.I) La classe TcpClient

Comme l’explique clairement MSDN, la classe TcpClient(System.Net.Sockets, dll : System) nous procure une manière de se connecter à un écouteur. Et aussi elle permet  de recevoir un flux de données et d’émettre un flux à un écouteur, tout ceci se faisant en mode synchrone bloquant. Remarque : l’espace de nom, System.Net.Sockets, nous montre qu’il s’agit bien de l’équivalent des sockets, mais avec un enrobage objet plus sympathique, et qui paraît moins bas niveau. Un écouteur est un processus qui écoute les demandes de connexion entrantes(entrantes car on cherche à se connecter au serveur, donc sens client->serveur). On peut créer un écouteur notamment avec la classe TcpListener, que nous verrons bientôt, mais aussi avec la classe Socket(System.Net.Sockets)(ce qui prouve d’ailleurs que TcpClient équivaut aux sockets !).

V.I.1) Construire un objet TcpClient

Constructeur intéressant :

 TcpClient monClientTcp = new TcpClient(nomServeur, port);

nomServeur est le nom DNS de l’ordinateur( le nom en toute lettre que vous lui avez donné), mais cela peut être aussi son adresse IP.

Le numéro de port est le numéro de port de l’ordinateur hôte.

Ce constructeur essaye de se connecter dès que vous l’utilisez.

Pour que la connexion puisse s’établir, il faut, bien entendu, qu’un objet TcpListener soit à l’écoute, ou encore un objet de la classe Socket(System.Net.Sockets).

Fermeture : monClientTcp.Close( ) ;

Exceptions intéressantes pouvant être déclenchées par ce constructeur : (System.Net.Sockets.).SocketException

V.I.2) Obtenir un objet NetworkStream

Une fois la connexion établit, vous avez besoin d’un objet de la classe NetworkStream pour pouvoir émettre ou recevoir des données.

Remarque sur la notion de client et de serveur:

 Attention, les termes client/serveur ne signifient pas que le client ne peut pas émettre, ou que le serveur ne peut pas recevoir. Le client, comme le serveur, peut émettre ET recevoir des données. La seule différence entre les 2, c’est que l’écouteur( le serveur) est toujours en attente d’une demande de connexion d’un client. Donc ce processus écouteur est toujours actif. Alors que le client peut avoir une vie limitée : il se connecte quand il veut, et s’arrête quand il le souhaite. Par conséquent, la notion de serveur et de client existe essentiellement par rapport à la notion de connexion, et pas par rapport à la capacité d’émettre ou de recevoir des données. Ne croyez donc pas qu’un serveur ne peut qu’émettre des données, et qu’un client ne peut qu’en recevoir. Un serveur peut émettre et recevoir des données, et un client peut aussi émettre et recevoir des données.

Pour ces raisons, je ne préfère pas utiliser des termes comme « émetteur » pour désigner un TcpListener, ni utiliser « récepteur » pour désigner un TcpClient. Je préfère appeler client Tcp un objet TcpCLient, et serveur Tcp ( ou écouteur Tcp), un objet TcpListener.

V.I.2.a) L’objet NetworkStream( System.Net.Sockets)

L’objet NetworkStream représente le concept de flux de donnée circulant sur le réseau. Pour envoyer ou recevoir des données depuis votre objet TcpClient, vous devez disposer d’un objet NetworkStream. Ce qui semble intuitif ! Une fois obtenu cet objet, il suffira d’appeler sa méthode de lecture( méthode Read) ou d’écriture(méthode Write).

Pour obtenir un objet NetworkStream associé à votre objet TcpClient, utilisez la méthode GetStream de votre TcpClient.

NetworkStream monFlux = monClientTcp.GetStream();

Fermeture : monFlux.Close( )

V.I.3) La méthode Write du NetworkStream

La méthode Write permet d’envoyer des données. La syntaxe est la suivante :

byte[] monWriteBuffer;

 

monFlux.Write(monWriteBuffer, 0/* offset dans le buffer*/,

monWriteBuffer.Length);

Le premier paramètre est un tableau d’octets contenant les données à envoyer.

Le deuxième paramètre est l’offset dans ce tableau d’octet, à partir duquel commencent les données à envoyer. Cela revient à dire que c’est l’indice, dans le tableau, de début des données à transmettre. Par exemple, avec un offset = 2, les données transmisent seront les données à partir de monWriteBuffer[2]. Ici nous mettons un offset à 0, c’est le cas le plus classique. Mais il peut être pratique de disposer de la possibilité de choisir l’indice de début des données.

Le troisième paramètre est la taille des données à transmettre.

Exceptions intéressantes pouvant être déclenchées :  (System.IO).IOException, ObjectDisposedException

Dans le cas où nous devons envoyer une string, qui est un message classique, la démarche est la suivante :

-          convertir la string en ASCII( l’ASCII n’est plus utilisé, donc la string n’est en général pas directement en ASCII).

-          Obtenir le résultat de cet conversion dans un tableau d’octets( byte[ ]) 

Une méthode faisant tout ce travail existe déjà. Il s’agit de la méthode GetBytes de l’attribut statique( attribut de classe) ASCII( qui est un objet de la classe Encoding), de la classe Encoding. La classe Encoding fait partie de l’espace de noms System.Encoding .

Autrement dit :

  string monMessage;

 

            /* Convertit la string en ASCII, et met le résultat dans un tableau d'octet */

monWriteBuffer = System.Text.Encoding.ASCII.GetBytes(monMessage.Text);

V.I.4) La méthode Read du NetworkStream

La méthode Read est semblable à la méthode write. Le premier paramètre est le tableau d’octets qui contiendra les données reçues. Le deuxième paramètre est toujours l’offset. Le troisième paramètre est le nombre d’octets à lire.

int nbLus = monFlux.Read(monReadBuffer, 0/*offset*/, monReadBuffer.Length);

                    //read peut déclencher exception

                    messageRecu =

                        System.Text.Encoding.ASCII.GetString(monReadBuffer, 0, nbLus/*tout le buffer n'est pas utilisé*/);

                    Console.WriteLine("Nb d'octet recus: ", nbLus);

Exceptions intéressantes pouvant être déclenchées :  (System.IO).IOException, ObjectDisposedExeption, ArgumentOutOfRangeException

V.I.4.a) Définition : synchrone

La méthode Read est synchrone, c’est-à-dire qu’elle va attendre de lire le nombre d’octets voulus, pour se terminer : elle est bloquante. Il y a donc une synchronisation entre celui qui a émis, et le déroulement du programme client, qui va bloquer jusqu’à ce que les deux programmes soit synchronisés.

V.II) La classe TcpListener

         La classe TcpListener permet d’obtenir un écouteur de connexion TCP. Les demandes de connexion peuvent provenir de la classe TcpClient vue ci-dessus, ou de la classe Socket. Ce qui prouve, une fois de plus, que les classes TcpClient et Socket sont, en réalité, équivalentes, et peuvent s’utiliser ensembles.

V.II.1) Création de l’objet TcpListener 

private string strIPhote="127.0.0.1";

IPhote = IPAddress.Parse(strIPhote); //conversion

monListenTcp = new TcpListener(IPhote, port); //le new ne déclenche pas d'exception

 

Le constructeur demande un objet de la classe IPAddress( System.Net), qu’il est aisé d’obtenir à partir d’une string, grâce à la méthode statique Parse, de la classe IPAddress. Le numéro de port est le numéro de port de l’ordinateur hôte.

 

Exceptions intéressantes pouvant être déclenchées par ce constructeur : aucune.

 

V.II.2) Le démarrage de l’écoute 

Le démarrage de l’écoute se fait par l’appel de la méthode start de votre objet TcpListener.

monListenTcp.Start(); //début de l'écoute des demandes de connexion                    

 

Exceptions intéressantes pouvant être déclenchées par ce constructeur : Uniquement (System.Net.Sockets.).SocketException

Une fois la méthode start appelée, il est nécessaire d’appeler une autre méthode : AcceptTcpClient, qui est bloquante. On en sort uniquement une fois qu’une connexion a été établie.

 

//Le AcceptTcpClient est bloquant: notre programme se bloque jusqu'à

            //ce que quelqu'un demande à se connecter

            monTcpClient = monListenTcp.AcceptTcpClient();

 

On récupère un objet qui représente notre TcpClient qui vient de se connecter. Cet objet va être très pratique, car il va nous permettre d’exprimer ce qu’on veut effectuer par rapport à notre client( recevoir des données, en émettre, etc). Et, de plus, il va s’utiliser de la même manière que n’importe quel TcpClient : obtention d’un NetWorkStream par GetStream, appel des méthodes Read quand on veut lire des données envoyées par le client, et Write quand on veut envoyer des données au client, etc…

 

V.II.3) L’arrêt de l’écoute 

La fermeture de l’écouteur se fait par un appel de la méthode stop de notre TcpListener.

 

monListenTcp.Stop();