Advertisement
Guest User

Untitled

a guest
Mar 29th, 2020
320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.52 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netdb.h>
  6. #include <stdlib.h>
  7. #include<arpa/inet.h>
  8. #include<string.h>
  9.  
  10. /* Rôle du client : envoyer une demande de connexion à un serveur,
  11.    envoyer une chaîne de caractères à ce serveur (la chaîne de
  12.    caractère est à saisir au clavier), recevoir un entier et comparer
  13.    cet entier avec le nombre d'octets envoyés. L'idée est de mettre en
  14.    place les bases qui vous permettront par la suite une mise en
  15.    oeuvre correcte des communications en TCP et de vérifier les
  16.    échanges effectués */
  17.  
  18. int main(int argc, char *argv[]) {
  19.  
  20.   /* je passe en paramètre l'adresse de la socket d'écoute du serveur
  21.      (IP et numéro de port). Je teste donc le passage de parametres */
  22.  
  23.   if (argc != 4){
  24.     printf("utilisation : %s ip_serveur port_serveur nombre_iteration\n", argv[0]);
  25.     exit(0);
  26.   }
  27.  
  28.   /* Etape 1 : créer une socket */  
  29.   int ds = socket(AF_INET, SOCK_STREAM, 0);
  30.  
  31.   /* /!\ : Il est indispensable de tester les valeurs de retour de
  32.      toutes les fonctions et agir en fonction des valeurs possibles.*/
  33.   if (ds == -1)
  34.   {
  35.     printf("Client : pb creation socket\n");
  36.     exit(1); // je choisis ici d'arrêter le programme car le reste
  37.          // dépendent de la réussite de la création de la socket.
  38.   }
  39.  
  40.   /* J'alimente le programme avec des traces d'exécution pour observer ce
  41.      qui se produit à l'exécution et pour mieux localiser les erreurs. */
  42.   printf("Client: creation de la socket : ok\n");
  43.  
  44.   // Je peux déjà tester l'exécution de cette étape avant de passer à la suite.
  45.  
  46.   /* Etape 2 : designer la socket du serveur : avoir une structure qui
  47.      contient l'adresse de cette socket (IP + numéro de port. */
  48.   struct sockaddr_in adrServ;
  49.   adrServ.sin_addr = *((struct in_addr*) gethostbyname(argv[1])->h_addr);
  50.   adrServ.sin_family = AF_INET;
  51.   adrServ.sin_port = htons(atoi(argv[2]));
  52.    
  53.   int lgAdr = sizeof(struct sockaddr_in);
  54.    
  55.   /* Etape 3 : envoyer une demande de connexion au serveur.*/
  56.   int conn = connect(ds, (struct sockaddr*) &adrServ, lgAdr);
  57.   // je traite les valeurs de retour
  58.   if (conn < 0)
  59.   {
  60.     perror ("Client: pb au connect :");
  61.     close (ds); // je libère les ressources avant de terminer.
  62.     exit (1); // je choisi de quitter le programme : la suite dépend
  63.           // de la réussite de l'envoi de la demande de connexion.
  64.   }
  65.  
  66.   // je continue à alimenter le programme avec traces d'exécution
  67.   printf("Client : demande de connexion reussie \n");
  68.  
  69.   // Je peux tester l'exécution de cette étape avant de passer à la suite.
  70.  
  71.   /* Etape 4 : envoyer un message au serveur. Ce message est une chaîne de caractères saisie au clavier. Vous pouvez utiliser une autre fonction pour la saisie. */
  72.  
  73.   printf("saisir un message à envoyer (moins de 200 caracteres) \n");
  74.   char m[1500];
  75.   fgets(m, sizeof(m), stdin); // copie dans m la chaîne saisie que
  76.                               // clavier (incluant les esaces et le
  77.                               // saut de ligne à la fin).
  78.   int len = strlen(m);
  79.   m[len-1]  = '\0'; // je retire le saut de ligne                                      
  80.  
  81.   /* Pour cet exercice, demander à envoyer la chaîne saisie avec un
  82.      seul appel à send(..). /!\ Envoyer uniquement les données
  83.      utiles. Par exemple, si je saisis la chaîne "bonjour Toto", je n'ai
  84.      pas à envoyer le tableau de 202 octets, mais seulement la chaîne
  85.      saisie (information utile)(refléchir à la raison). Remarque : le
  86.      serveur s'attends à recevoir une chaine de caractères y compris le
  87.      caractère de fin */
  88.  
  89.   int iter = atoi(argv[3]);
  90.   int total = 0;
  91.  
  92.   for(int i = 0; i < iter; i++)
  93.   {
  94.     int snd = send(ds, m, len, 0);
  95.    
  96.     if(snd == -1)
  97.     {
  98.         perror("Client: pb au send : ");
  99.         close(ds);
  100.         exit(1);
  101.     }
  102.     else
  103.     {
  104.         total += snd;
  105.     }
  106.   }
  107.   /* Afficher le nombre d'octets EFFECTIVEMENT déposés dans le buffer
  108.      d'envoi de la socket cliente. : /!\ Faire la différence entre le
  109.      nombre d'octet qu'on demande à déposer / envoyer et le nombre
  110.      d'octets qu'on a effectivement déposés.*/
  111.  
  112.   printf("Client : j'ai déposé %d octets, %d octets supposément envoyés sur %i itérations \n", total, len * iter, iter);
  113.  
  114.  
  115.   // Je peux tester l'exécution de cette étape avant de passer à la suite.
  116.  
  117.   /* Etape 5 : reception d'une réponse du serveur. La réponse est un
  118.      entier représentant le nombre d'octets du message que le serveur
  119.      a effectivement reçu à l'étape précédente. Pour cet exercice,
  120.      faire un seul appel de la fonction recv(..). */
  121.  
  122.   /* /!\j'alimente toujours le programme avec traces d'exécution. A noter
  123.      qu'il est aussi important d'afficher un message avant une action
  124.      qui peut être bloquante. Vous saurez ainsi à quelle étape de
  125.      l'exécution le blocage se produit. */
  126.  
  127.   printf("Client : envoi fait, j'attends la reponse du serveur \n");
  128.  
  129.   int reponse;
  130.   int rcv = recv(ds, &reponse, sizeof(int), 0);
  131.  
  132.   if(rcv == -1)
  133.   {
  134.     perror("Client: pb au recv : ");
  135.     close(ds);
  136.     exit(1);
  137.   }
  138.   else if(rcv == 0)
  139.   {
  140.     printf("le serveur a fermé la connexion\n");
  141.   }
  142.  
  143.  
  144.   /* Etape 6 : je compare le nombre d'octets déposés (envoyés) avec
  145.      la valeur reçue. L'objectif est d'avoir la même valeur. */
  146.  
  147.   printf("Client : j'ai envoyé %d octets et le serveur me répond qu'il a reçu : %d octets \n", len, reponse) ;
  148.  
  149.  
  150.   /* Etape 7 : je termine proprement. */
  151.  
  152.   close (ds);
  153.   printf("Client : je termine\n");
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement