Mode connecte en C++

Mode connecte en C++

1 – Schéma d’une relation client-serveur

Voici le schéma d’une relation mode connecté entre un client et un serveur.

c-mode-connecte schema relation client serveur

2 – Initialisation de la socket

Une socket est un mécanisme de couche 5 permettant une communication réseau inter application. En résumé, elle permet la communication entre deux applications situés sur deux machines distinctes.

2.1 Commande WSAStartup()

Windows se basant sur Winsock, nous devons initialiser cette API, contrairement à Linux. Pour cela, nous allons utiliser la fonction WSAStartup(). L’utilisation de cette fonction est donc obligatoire pour un système d’exploitation Windows. Si vous utilisez un autre OS, alors passez directement à l’étape suivante. Voici un exemple d’utilisation pour le côté client et serveur.

// ********************************************************
// Déclaration des variables
// ********************************************************
WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
 
// ********************************************************
// Initialisation de Winsock
// ********************************************************
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
if (erreur!=0)
      printf("\nDesole, je ne peux pas initialiser Winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
else
      printf("\nWSAStartup  : OK");
  • Le premier paramètre indique la version de Winsock que nous demandons.
  • Le second paramètre est l’adresse d’une structure de type WSADATA qui contient toutes les informations nécessaires résultant de l’initialisation.
  • La fonction devra renvoyer 0 pour indiquer que sont exécution c’est correctement déroulée.

2.2 – Commande socket()

La création d’une socket est obligatoire afin d’obtenir un identifiant unique. Cela permettra aux prochaines fonctions de toutes ce référencer au même id, donc à la même socket. Voici un exemple d’utilisation pour le côté client et serveur.

// ********************************************************
// Déclaration des variables
// ********************************************************
SOCKET id_de_la_socket; // Identifiant de la socket
 
// ********************************************************
// Ouverture d'une Socket
// ********************************************************
id_de_la_socket=socket(AF_INET,SOCK_STREAM,0);
if (id_de_la_socket==INVALID_SOCKET)
      printf("\nDesole, je ne peux pas creer la socket du a l'erreur : %d",WSAGetLastError());
else
      printf("\nsocket      : OK");
  • Le premier paramètre indique que vous désirez crée une socket basé sur le protocole IPv4.
  • Le second paramètre sélectionne le mode connecté via TCP, cela nécessitera alors une ouverture de session.
  • La fonction  retournera l’identifiant de la socket si elle s’est exécutée correctement. Sinon, elle indiquera la valeur INVALID_SOCKET.

2.3 – Commande setsockopt()

La configuration des options de la socket n’est pas obligatoire. Vous devez l’utilisez que si vous avez un besoin spécifique. Voici un exemple d’utilisation pour le côté client et serveur.

// ********************************************************
// Déclaration des variables
// ********************************************************
int tempo; // Variable temporaire de type int
 
// ********************************************************
// Activation de l'option permettant d'activer l'algorithme de Nagle
// ********************************************************
tempo=1;
erreur=setsockopt(id_de_la_socket,IPPROTO_TCP,TCP_NODELAY,(char *)&tempo,sizeof(tempo));
if (erreur!=0)
      printf("\nDesole, je ne peux pas configurer cette options du à l'erreur : %d %d",erreur,WSAGetLastError());
else
      printf("\nsetsockopt  : OK");
  • Le premier argument est l’identifiant de la socket que vous avez récupéré grâce à la fonction socket().
  • Le second paramètre spécifie le niveau de l’option.
  • Le troisième paramètres indique l’option à configurer. Dans cette exemple, la passage à 1, de TCP_NODELAY, permet d’activer l’algorithme de Nagle décrit dans la RFC 896. Il apportera une meilleur gestion dans le cadre d’envoi de très petite donnée.
  • Le quatrième paramètre indique la valeur de l’option que l’on spécifie.
  • Le cinquième paramètre spécifie uniquement la taille du quatrième.
  • La fonction devra renvoyer 0 pour indiquer que sont exécution c’est correctement déroulée.

3 – Ecoute du port TCP

3.1 – Commande bind()

La commande bind permet de lier la socket à un port et adresse IP d’écoute. Voici un exemple d’utilisation pour le côté serveur.

// ********************************************************
// Déclaration des variables
// ********************************************************
SOCKADDR_IN information_sur_la_source; // Déclaration de la structure des informations lié à l'écoute

// ********************************************************
// Lie la socket à une ip et un port d'écoute
// ********************************************************
information_sur_la_source.sin_family=AF_INET;
information_sur_la_source.sin_addr.s_addr=INADDR_ANY; // Ecoute sur toutes les IP locales  
information_sur_la_source.sin_port=htons(33333); // Ecoute sur le port 33333
erreur=bind(id_de_la_socket,(struct sockaddr*)&information_sur_la_source,sizeof(information_sur_la_source));
if (erreur!=0)
      printf("\nDesole, je ne peux pas ecouter ce port : %d %d",erreur,WSAGetLastError());
else
      printf("\nbind        : OK");
  • Le premier argument est l’identifiant de la socket que vous avez récupéré grâce à la fonction socket().
  • Le second argument est la structure comprenant les informations sur le port et l’adresse IP à se lier.
  • Le troisième paramètre spécifie uniquement la taille de la structure du second.
  • La fonction devra renvoyer 0 pour indiquer que sont exécution c’est correctement déroulée.

4 – Établissement d’une session TCP

Le client doit utiliser la fonction connect() afin d’amorcer l’ouverture de session TCP. Et le serveur doit appeler la fonction accept() pour valider l’ouverture. Le but de ces fonctions est de créer la session TCP basé sur trois trames S,AS,A. Cette étape n’est donc nécessaire que dans le cadre de l’utilisation du mode connecté.

4.1 – Commande connect()

La commande connect permet d’initier et d’établir la session TCP avec le serveur. Voici un exemple d’utilisation pour le côté client.

// ********************************************************
// Déclaration des variables
// ********************************************************
SOCKADDR_IN information_sur_la_destination; // Déclaration de la structure des informations lié au serveur

// ********************************************************
// Ouverture de la session TCP sur destination de l'adresse IP 10.10.10.10 et du port 80
// ********************************************************
information_sur_la_destination.sin_family=AF_INET;
information_sur_la_destination.sin_addr.s_addr=inet_addr("10.10.10.10"); // Indiquez l'adresse IP de votre serveur
information_sur_la_destination.sin_port=htons(80); // Port écouté du serveur (33333)
erreur=connect(id_de_la_socket,(struct sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination));
if (erreur!=0)
      printf("\nDesole, je n'ai pas pu ouvrir la session TCP : %d %d",erreur,WSAGetLastError());
else
      printf("\nsetsockopt  : OK");
  • Le premier argument est l’identifiant de la socket que vous avez récupéré grâce à la fonction socket().
  • Le second argument est la structure comprenant les informations sur la destination du port et sur l’adresse IP.
  • Le troisième paramètre spécifie uniquement la taille de la structure du second.
  • La fonction devra renvoyer 0 pour indiquer que son exécution c’est correctement déroulée.

4.2 – Commande listen()

La commande listen permet d’écouter les demandes d’ouvertures de session TCP arrivant sur le port et adresse IP sélectionné par la commande bind(). Voici un exemple d’utilisation pour le côté serveur.

// ********************************************************
// Attente d'ouverture de session
// ********************************************************
erreur=99; // Initiation de erreur pour être sur que l'on va rentrer dans la boucle
while(erreur!=0) // Boucle tant qu'une demande de session (SYN) tcp n'a pas été reçu
      erreur=listen(id_de_la_socket,1);
printf("\nlisten      : OK");
  • Le premier argument est l’identifiant de la socket que vous avez récupéré grâce à la fonction socket().
  • Le second argument représente le nombre maximum de demande d’ouverture de session simultanée accepté.
  • La fonction devra renvoyer 0 pour indiquer qu’une session TCP a été établie.

4.3 – Commande accept()

La commande accept permet d’indiquer, après réception du SYN (demande d’ouverture de session TCP), l’acceptation de l’établissement complète de la session. Voici un exemple d’utilisation pour le côté serveur.

// ********************************************************
// Déclaration des variables
// ********************************************************
SOCKET id_de_la_nouvelle_socket; // Identifiant de la nouvelle socket
SOCKADDR_IN information_sur_la_source; // Déclaration de la structure des informations lié à l'écoute

// ********************************************************
// Acceptation de la demande d'ouverture de session
// ********************************************************
printf("\nAttente de la reception de demande d'ouverture de session tcp (SYN)");
tempo=sizeof(information_sur_la_source); // Passe par une variable afin d'utiliser un pointeur
id_de_la_nouvelle_socket=accept(id_de_la_socket,(struct sockaddr*)&information_sur_la_source,&tempo);
if(id_de_la_nouvelle_socket==INVALID_SOCKET)
      printf("\nDesole, je ne peux pas accepter la session TCP du a l'erreur : %d",WSAGetLastError());
else
      printf("\naccept      : OK");
  • Le premier argument est l’identifiant de la socket que vous avez récupéré grâce à la fonction socket().
  • Le second argument est la structure comprenant les informations sur la source du port et de l’adresse IP qui ont été récupérées.
  • Le troisième paramètre spécifie uniquement la taille de la structure du second.
  • La fonction renverra le descripteur d’une nouvelle socket permettant l’envoi des données via la session TCP ouverte.

5 – Echange des données

5.1 – Commande send()

La commande send permet l’envoi d’une chaîne de caractère à destination du serveur ayant établi la session TCP. Voici un exemple d’utilisation pour le côté client.

// ********************************************************
// Déclaration des variables
// ********************************************************
int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
char buffer[65535]; // Tampon contenant les données reçues ou envoyées

// ********************************************************
// Envoi des données
// ********************************************************
strcpy(buffer,"Coucou, je suis les donnees. www.frameip.com"); // Copie la chaine de caractère dans buffer
nombre_de_caractere=send(id_de_la_socket,buffer,strlen(buffer),0);
if (nombre_de_caractere==SOCKET_ERROR)
      printf("\nDesole, je n'ai pas envoyer les donnees du a l'erreur : %d",WSAGetLastError());
else
      printf("\nsend        : OK");
  • Le premier argument est l’identifiant de la socket que vous avez récupéré grâce à la fonction socket().
  • Le second argument est le buffer contenant les données à envoyer.
  • Le troisième paramètre spécifie uniquement la taille du buffer.
  • La fonction renverra le nombre de caractère qui a été émis.

5.2 – Commande recv()

La commande recv permet de recueillir dans un buffer les données reçues sur une socket. Voici un exemple d’utilisation pour le côté serveur.

// ********************************************************
// Reception des données
// ********************************************************
nombre_de_caractere=recv(id_de_la_nouvelle_socket,buffer,1515,0);
if (nombre_de_caractere==SOCKET_ERROR)
      printf("\nDesole, je n'ai pas recu de donnee");
else
     {
      buffer[nombre_de_caractere]=0; // Permet de fermer le tableau après le contenu des data, car la fonction recv ne le fait pas
      printf("\nVoici les donnees : %s",buffer);
      }
  • Le premier argument est l’identifiant de la socket que vous avez récupéré grâce à la fonction accept().
  • Le second argument est le buffer contenant les données à recevoir.
  • Le troisième paramètre représente le nombre maximum de caractère attendu.
  • La fonction renverra le nombre de caractère qui a été reçu.

6 – Fermeture de la session TCP

6.1 Commande shutdown()

La fermeture de session TCP n’est pas obligatoire dû fait que vous aurez déjà obtenue les services attendus. Cependant ces très fortement conseillé pour un développement propre et une utilisation respectueuse du protocole IP. Voici un exemple d’utilisation pour le côté client et serveur.

// ********************************************************
// Fermeture de la session TCP Correspondant à la commande connect()
// ********************************************************
erreur=shutdown(id_de_la_socket,2); // 2 signifie socket d'émission et d'écoute
if (erreur!=0)
      printf("\nDesole, je ne peux pas fermer la session TCP du a l'erreur : %d %d",erreur,WSAGetLastError());
else
      printf("\nshutdown    : OK");  
  • Le premier argument est l’identifiant de la socket que vous avez récupéré grâce à la fonction socket().
  • Le second argument indique si l’on doit fermer l’émission, la réception ou les deux.
  • La fonction devra renvoyer 0 pour indiquer que sont exécution c’est correctement déroulée.

7 – Libération de la socket

7.1 Commande closesocket()

Cette fonction permet de libérer proprement l’accès à la socket. Durement conseillé pour le respect d’un développement propre et d’une utilisation saine du système d’exploitation. Voici un exemple d’utilisation pour le côté client et serveur.

// ********************************************************
// Fermeture de la socket correspondant à la commande socket()
// ********************************************************
erreur=closesocket(id_de_la_socket);
if (erreur!=0)
      printf("\nDesole, je ne peux pas liberer la socket du a l'erreur : %d %d",erreur,WSAGetLastError());
else
      printf("\nclosesocket : OK");
  • Le premier argument est l’identifiant de la socket que vous avez récupéré grâce à la fonction socket().
  • La fonction devra renvoyer 0 pour indiquer que sont exécution c’est correctement déroulée.

7.2 Commande WSACleanup()

Cette étape n’est utile et fonctionnelle que dans le cadres du système d’exploitation Microsoft. Cette fonction permet de libérer l’accès à Winsock. Attention, dans un environnement multiprocess, l’utilisation de cette commande fermera les accès de tous les process. Voici un exemple d’utilisation pour le côté client et serveur.

// ********************************************************
// Quitte proprement le winsock ouvert avec la commande WSAStartup
// ********************************************************
erreur=WSACleanup(); // A appeler autant de fois qu'il a été ouvert.
if (erreur!=0)
      printf("\nDesole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
else
      printf("\nWSACleanup  : OK");
  • La fonction devra renvoyer 0 pour indiquer que sont exécution c’est correctement déroulée.

8 – Exemple complet d’une communication client serveur

8.1 – Côté serveur

Voici un exemple de code fonctionnel qui permet d’écouter sur le port TCP 33333 et d’afficher les données reçues. Le fichier cpp est disponible ici.

// ********************************************************
// Les includes
// ********************************************************
#include <winsock2.h> // pour les fonctions socket
#include <cstdio> // Pour les Sprintf
 
// ********************************************************
// Les librairies
// ********************************************************
#pragma comment(lib,"ws2_32.lib")
 
// ********************************************************
// Définition des variables
// ********************************************************
WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
int tempo; // Variable temporaire de type int
int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
char buffer[65535]; // Tampon contenant les données reçues ou envoyées
SOCKET id_de_la_socket; // Identifiant de la socket
SOCKET id_de_la_nouvelle_socket; // Identifiant de la nouvelle socket
SOCKADDR_IN information_sur_la_source; // Déclaration de la structure des informations lié à l'écoute
 
int main (int argc, char* argv[])
      {
      printf("\nBonjour, vous etes du cote serveur. www.frameip.com\n");
 
      // ********************************************************
      // Initialisation de Winsock
      // ********************************************************
      erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
      if (erreur!=0)
            printf("\nDesole, je ne peux pas initialiser Winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nWSAStartup  : OK");
 
      // ********************************************************
      // Ouverture d'une Socket
      // ********************************************************
      id_de_la_socket=socket(AF_INET,SOCK_STREAM,0);
      if (id_de_la_socket==INVALID_SOCKET)
            printf("\nDesole, je ne peux pas creer la socket du a l'erreur : %d",WSAGetLastError());
      else
            printf("\nsocket      : OK");
 
      // ********************************************************
      // Activation de l'option permettant d'activer l'algorithme de Nagle
      // ********************************************************
      tempo=1;
      erreur=setsockopt(id_de_la_socket,IPPROTO_TCP,TCP_NODELAY,(char *)&tempo,sizeof(tempo));
      if (erreur!=0)
            printf("\nDesole, je ne peux pas configurer cette options du à l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nsetsockopt  : OK");
 
      // ********************************************************
      // Lie la socket à une ip et un port d'écoute
      // ********************************************************
      information_sur_la_source.sin_family=AF_INET;
      information_sur_la_source.sin_addr.s_addr=INADDR_ANY; // Ecoute sur toutes les IP locales  
      information_sur_la_source.sin_port=htons(33333); // Ecoute sur le port 33333
      erreur=bind(id_de_la_socket,(struct sockaddr*)&information_sur_la_source,sizeof(information_sur_la_source));
      if (erreur!=0)
            printf("\nDesole, je ne peux pas ecouter ce port : %d %d",erreur,WSAGetLastError());
      else
            printf("\nbind        : OK");

      // ********************************************************
      // Attente d'ouverture de session
      // ********************************************************
      erreur=99; // Initiation de erreur pour être sur que l'on va rentrer dans la boucle
      while(erreur!=0) // Boucle tant qu'une demande de session (SYN) tcp n'a pas été reçu
            erreur=listen(id_de_la_socket,1);
      printf("\nlisten      : OK");
 
      // ********************************************************
      // Acceptation de la demande d'ouverture de session
      // ********************************************************
      printf("\nAttente de la reception de demande d'ouverture de session tcp (SYN)");
      tempo=sizeof(information_sur_la_source); // Passe par une variable afin d'utiliser un pointeur
      id_de_la_nouvelle_socket=accept(id_de_la_socket,(struct sockaddr*)&information_sur_la_source,&tempo);
      if(id_de_la_nouvelle_socket==INVALID_SOCKET)
            printf("\nDesole, je ne peux pas accepter la session TCP du a l'erreur : %d",WSAGetLastError());
      else
           printf("\naccept      : OK");
 
      // ********************************************************
      // Reception des données
      // ********************************************************
      nombre_de_caractere=recv(id_de_la_nouvelle_socket,buffer,1515,0);
      if (nombre_de_caractere==SOCKET_ERROR)
            printf("\nDesole, je n'ai pas recu de donnee");
      else
            {
            buffer[nombre_de_caractere]=0; // Permet de fermer le tableau après le contenu des data, car la fonction recv ne le fait pas
            printf("\nVoici les donnees : %s",buffer);
            }
 
      // ********************************************************
      // Fermeture de la session TCP Correspondant à la commande connect()
      // ********************************************************
      erreur=shutdown(id_de_la_nouvelle_socket,2); // 2 signifie socket d'émission et d'écoute
      if (erreur!=0)
            printf("\nDesole, je ne peux pas fermer la session TCP du a l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nshutdown    : OK");
 
      // ********************************************************
      // Fermeture des deux socket correspondant à la commande socket() et accept()
      // ********************************************************
      erreur=closesocket(id_de_la_nouvelle_socket);
      if (erreur!=0)
            printf("\nDesole, je ne peux pas liberer la socket du a l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nclosesocket : OK");
      erreur=closesocket(id_de_la_socket);
      if (erreur!=0)
            printf("\nDesole, je ne peux pas liberer la socket du a l'erreur : %d %d",erreur,WSAGetLastError());
       else
            printf("\nclosesocket : OK");
 
      // ********************************************************
      // Quitte proprement le winsock ouvert avec la commande WSAStartup
      // ********************************************************
      erreur=WSACleanup(); // A appeler autant de fois qu'il a été ouvert.
      if (erreur!=0)
            printf("\nDesole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nWSACleanup  : OK");
      }

8.2 – Côté client

Voici un exemple de code fonctionnel qui permet d’envoyer des données sur le port TCP 33333, n’oubliez pas de changer l’IP de destination pour correspondre à votre serveur. Le fichier cpp est disponible ici.

// ********************************************************
// Les includes
// ********************************************************
#include <winsock2.h> // pour les fonctions socket
#include <cstdio> // Pour les Sprintf

// ********************************************************
// Les librairies
// ********************************************************
#pragma comment(lib,"ws2_32.lib")

// ********************************************************
// Définition des variables
// ********************************************************
WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
int tempo; // Variable temporaire de type int
int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
char buffer[65535]; // Tampon contennant les données reçues ou envoyées
SOCKET id_de_la_socket; // Identifiant de la socket
SOCKADDR_IN information_sur_la_destination; // Déclaration de la structure des informations lié au serveur

int main (int argc, char* argv[])
      {
      printf("\nBonjour, vous etes du cote client. www.frameip.com\n");
 
      // ********************************************************
      // Initialisation de Winsock
      // ********************************************************
      erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
      if (erreur!=0)
            printf("\nDesole, je ne peux pas initialiser Winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nWSAStartup  : OK");
 
      // ********************************************************
      // Ouverture d'une Socket
      // ********************************************************
      id_de_la_socket=socket(AF_INET,SOCK_STREAM,0);
      if (id_de_la_socket==INVALID_SOCKET)
            printf("\nDesole, je ne peux pas creer la socket du a l'erreur : %d",WSAGetLastError());
      else
            printf("\nsocket      : OK");
 
      // ********************************************************
      // Activation de l'option permettant d'activer l'algorithme de Nagle
      // ********************************************************
      tempo=1;
      erreur=setsockopt(id_de_la_socket,IPPROTO_TCP,TCP_NODELAY,(char *)&tempo,sizeof(tempo));
      if (erreur!=0)
            printf("\nDesole, je ne peux pas configurer cette options du à l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nsetsockopt  : OK");
 
      // ********************************************************
      // Etablissement de l'ouverture de session
      // ********************************************************
      information_sur_la_destination.sin_family=AF_INET;
      information_sur_la_destination.sin_addr.s_addr=inet_addr("10.10.10.10"); // Indiquez l'adresse IP de votre serveur  
      information_sur_la_destination.sin_port=htons(33333); // Port écouté du serveur (33333)
      erreur=connect(id_de_la_socket,(struct sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination));
      if (erreur!=0)
            printf("\nDesole, je n'ai pas pu ouvrir la session TCP : %d %d",erreur,WSAGetLastError());
      else
            printf("\nsetsockopt  : OK");
 
      // ********************************************************
      // Envoi des données
      // ********************************************************
      strcpy(buffer,"Coucou, je suis les donnees. www.frameip.com"); // Copie la chaine de caractère dans buffer
      nombre_de_caractere=send(id_de_la_socket,buffer,strlen(buffer),0);
      if (nombre_de_caractere==SOCKET_ERROR)
            printf("\nDesole, je n'ai pas envoyer les donnees du a l'erreur : %d",WSAGetLastError());
      else
            printf("\nsend        : OK");
 
      // ********************************************************
      // Fermeture de la session TCP Correspondant à la commande connect()
      // ********************************************************
      erreur=shutdown(id_de_la_socket,2); // 2 signifie socket d'émission et d'écoute
      if (erreur!=0)
            printf("\nDesole, je ne peux pas fermer la session TCP du a l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nshutdown    : OK");
 
      // ********************************************************
      // Fermeture de la socket correspondant à la commande socket()
      // ********************************************************
      erreur=closesocket(id_de_la_socket);
      if (erreur!=0)
            printf("\nDesole, je ne peux pas liberer la socket du a l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nclosesocket : OK");
 
      // ********************************************************
      // Quitte proprement le winsock ouvert avec la commande WSAStartup
      // ********************************************************
      erreur=WSACleanup(); // A appeler autant de fois qu'il a été ouvert.
      if (erreur!=0)
            printf("\nDesole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
      else
            printf("\nWSACleanup  : OK");
      }

9 – Suivi du document

Création et suivi de la documentation par _SebF

10 – Discussion autour du mode connecte en C++

Vous pouvez poser toutes vos questions, faire part de vos remarques et partager vos expériences à propos du mode connecte en C++. Pour cela, n’hésitez pas à laisser un commentaire ci-dessous :

Commentaire et discussion

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *