PROGRAMMATION RÉSEAU

Prorammation client-serveur TCP/UDP

RAPPELS PROTOCOLE UDP

RAPPELS PROTOCOLE TCP

PROTOCOLE TCP

Établissement d'une connexion

Poignée de main (3 temps)

PROTOCOLE TCP

Terminaison d'une connexion

Poignée de main (2 temps)

CONNEXION TCP

Caractérisée par 5 paramètres :

  • protocole
  • IP source
  • port source
  • IP destination
  • port destination

Ces 5 paramètres sont connus des deux côtés de la connexion.

PROGRAMMATION CLIENT-SERVEUR

Fonctions/primitives de communication et analogie téléphonique

  • socket : posséder une ligne et un téléphone actifs.
  • bind : déclarer son numéro pour pouvoir être joint.
  • listen : avoir une sonnerie pour détecter les appels entrants.
  • connect : composer le numéro du contact à appeler.
  • accept : répondre à un appel.
  • shutdown : terminer l'appel.

Fonctions d'échange de données

  • send et recv en mode connecté (TCP)
  • sendto et recvfrom en mode non-connecté (UDP)

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Serveur itératif

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Serveur parallèle

PROGRAMMATION CLIENT-SERVEUR

Mode connecté : TCP

Serveur itératif

PROGRAMMATION CLIENT-SERVEUR

Mode connecté : TCP

Serveur parallèle

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Création d'une socket

#include <sys/socket.h>
int socket(
      int domaine,
      int type,
      int protocole );

Retourne le descripteur (int) en cas de succès, -1 en cas d'échec.

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Association d'une socket à une adresse

#include <sys/socket.h>
int bind(
      int descripteur,
      struct sockaddr * addresse,
      int longueur_adresse );

#include <netinet/in.h>
struct in_addr{                 //adresse internet machine
       u_long s_addr ; };

struct sockaddr_in{             //adresse internet socket
       short sin_family ;       //AF_INET
       u_short sin_port ;       //numéro de port
       struct in_addr sin_addr ;
       char sin_zero[8] ; };    // 8 char nuls

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Transcodage du format d'adresse

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Traduction d'adresse

#include <netdb.h>
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                char *host, size_t hostlen,
                char *serv, size_t servlen, int flags);
int getaddrinfo(const char *node, const char *service,
                const struct addrinfo *hints,
                struct addrinfo **res);

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Réception de données

#include <sys/socket.h>
int recvfrom(
       int descripteur,
       void * message,
       int longueur,
       int option,
       struct sockaddr * adresse,
       int * longueur_adresse );

Retourne le nombre de caractères lus en cas de succès et -1 en cas d'échec. Primitive bloquante.

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Émission de données

#include <sys/socket.h>
int sendto(
      int descripteur,
      void * message,
      int longueur,
      int option,
      struct sockaddr, adresse,
      int longueur_adresse );

Retourne le nombre de caractères effectivement envoyés.

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Fermeture de socket

#include <unistd.h>
int close(int descripteur);

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Exemple serveur itératif

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>     // pour memset

int main(int argc, char**argv)
{
   int sockfd,n;                       //descripteurs
   struct sockaddr_in servaddr,cliaddr;//adresses sockets
   socklen_t len;                      //longueur sockaddr_in
   char mesg[1000];

   sockfd=socket(AF_INET,SOCK_DGRAM,0);

   memset(&servaddr,0,sizeof(servaddr));//mise à 0
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr=htonl(INADDR_ANY);//toutes les adresses de l'hôte
   servaddr.sin_port=htons(32000);            //traduction du n° de port
   bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

   while(1)
   {
      len = sizeof(cliaddr);
      n = recvfrom(sockfd,mesg,1000,0,(struct sockaddr *)&cliaddr,&len);
      sendto(sockfd,mesg,n,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
      mesg[n] = '\0';
      printf("Reçu la chaîne:\n");
      printf("%s",mesg);
      printf("-------------------------------------------------------\n");
   }
}

PROGRAMMATION CLIENT-SERVEUR

Mode non-connecté : UDP

Exemple client

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>   // pour memset

int main(int argc, char**argv)
{
   int sockfd,n;
   struct sockaddr_in servaddr,cliaddr;
   char sendline[1000];
   char recvline[1000];

   if (argc != 2){
     printf("usage:  udp-client <adresse IP>\n");
     return EXIT_FAILURE;  }

   sockfd=socket(AF_INET,SOCK_DGRAM,0);
   memset(&servaddr,0, sizeof(servaddr));
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr=inet_addr(argv[1]);
   servaddr.sin_port=htons(32000);

   while (fgets(sendline, 10000,stdin) != NULL) // lecture STDIN
   {
      sendto(sockfd,sendline,strlen(sendline),0,
             (struct sockaddr *)&servaddr,sizeof(servaddr)); //envoi
      n=recvfrom(sockfd,recvline,10000,0,NULL,NULL);         //réception écho
      recvline[n] = '\0';
      fputs(recvline,stdout);
   }
}

PROGRAMMATION CLIENT-SERVEUR

Mode connecté : TCP

Serveur parallèle

int main(int argc, char**argv){
   int listenfd,connfd,n;
   struct sockaddr_in servaddr,cliaddr;
   socklen_t clilen;
   pid_t     childpid;
   char mesg[1000];

   listenfd=socket(AF_INET,SOCK_STREAM,0);
   memset(&servaddr,0, sizeof(servaddr));
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
   servaddr.sin_port=htons(32000);
   bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

   listen(listenfd,1024);
   while(1) {
      clilen=sizeof(cliaddr);
      connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
      if ((childpid = fork()) == 0){
         close (listenfd) ;
         do {
             n = recv(connfd,mesg,1000,0);
             sendto(connfd,mesg,n,0);
             mesg[n] = '\0';
             printf("Reçu\n%s", mesg); printf("---------------------\n");
         } while (n!=0 && n<1000);
         exit(0);
      }
      close(connfd);
   }}

PROGRAMMATION CLIENT-SERVEUR

Mode connecté : TCP

Client

int main(int argc, char**argv) {
   int sockfd,n;
   struct sockaddr_in servaddr,cliaddr;
   char sendline[1000];
   char recvline[1000];

   if (argc != 2) {
      printf("usage:  client <IP address>\n");
      return EXIT_FAILURE; }

   sockfd=socket(AF_INET,SOCK_STREAM,0);
   memset(&servaddr,0, sizeof(servaddr));
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr=inet_addr(argv[1]);
   servaddr.sin_port=htons(32000);

   connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
   while (fgets(sendline, 10000,stdin) != NULL) {
      send(sockfd,sendline,strlen(sendline),0);
      n=recv(sockfd,recvline,10000,0);
      recvline[n]='\0';
      fputs(recvline,stdout);
      }
}
SpaceForward
Left, Down, Page DownNext slide
Right, Up, Page UpPrevious slide
POpen presenter console
HToggle this help