Changes between Version 1 and Version 2 of IOC_T06


Ignore:
Timestamp:
Apr 19, 2019, 11:52:37 AM (5 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • IOC_T06

    v1 v2  
    3131      * Si ok, le serveur envoie le message « a voté »
    3232      * Si ko, le serveur envoie le message « erreur, vote déjà réalisé »
    33  
    34 [[Image(png/client-serveur.png)]]
     33
     34** Schéma de principe d'un échange client-serveur avec le protocole TCP (connecté)
     35   [[Image(htdocs:png/client-serveur.png,300px,nolink)]]
     36   
     37Illustration dans un programme où le client envoie un message à un serveur (qui ne lui répond pas).
     38
     39** client.c :
     40{{{
     41#!c
     42#include <stdio.h>
     43#include <stdlib.h>
     44#include <unistd.h>
     45#include <string.h>
     46#include <sys/types.h>
     47#include <sys/socket.h>
     48#include <netinet/in.h>
     49#include <netdb.h>
     50
     51void error(const char *msg)
     52{
     53        perror(msg);
     54        exit(0);
     55}
     56
     57int main(int argc, char *argv[])
     58{
     59        int sockfd, portno, n;
     60        struct sockaddr_in serv_addr;
     61        struct hostent *server;
     62
     63        char buffer[256];
     64
     65        // Le client doit connaitre l'adresse IP du serveur, et son numero de port
     66        if (argc < 3) {
     67                fprintf(stderr,"usage %s hostname port\n", argv[0]);
     68                exit(0);
     69        }
     70        portno = atoi(argv[2]);
     71       
     72        // 1) Création de la socket, INTERNET et TCP
     73
     74        sockfd = socket(AF_INET, SOCK_STREAM, 0);
     75        if (sockfd < 0)
     76                error("ERROR opening socket");
     77
     78        server = gethostbyname(argv[1]);
     79        if (server == NULL) {
     80                fprintf(stderr,"ERROR, no such host\n");
     81                exit(0);
     82        }
     83
     84        // On donne toutes les infos sur le serveur
     85
     86        bzero((char *) &serv_addr, sizeof(serv_addr));
     87        serv_addr.sin_family = AF_INET;
     88        bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
     89        serv_addr.sin_port = htons(portno);
     90
     91        // On se connecte. L'OS local nous trouve un numéro de port, grâce auquel le serveur
     92        // peut nous renvoyer des réponses, le \n permet de garantir que le message ne reste
     93        // pas en instance dans un buffer d'emission chez l'emetteur (ici c'est le clent).
     94
     95        if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
     96                error("ERROR connecting");
     97
     98        strcpy(buffer,"Coucou Peri\n");
     99        n = write(sockfd,buffer,strlen(buffer));
     100
     101        // On ferme la socket
     102
     103        close(sockfd);
     104        return 0;
     105}
     106}}}
     107
     108** server.c
     109{{{
     110#!c
     111#include <string.h>
     112#include <unistd.h>
     113#include <sys/types.h>
     114#include <sys/socket.h>
     115#include <netinet/in.h>
     116
     117#include <netdb.h>
     118#include <arpa/inet.h>
     119
     120
     121void error(const char *msg)
     122{
     123        perror(msg);
     124        exit(1);
     125}
     126
     127int main(int argc, char *argv[])
     128{
     129        int sockfd, newsockfd, portno;
     130        socklen_t clilen;
     131        char buffer[256];
     132        struct sockaddr_in serv_addr, cli_addr;
     133        int n;
     134
     135        if (argc < 2) {
     136                fprintf(stderr, "ERROR, no port provided\n");
     137                exit(1);
     138        }
     139
     140        // 1) on crée la socket, SOCK_STREAM signifie TCP
     141
     142        sockfd = socket(AF_INET, SOCK_STREAM, 0);
     143        if (sockfd < 0)
     144                error("ERROR opening socket");
     145
     146        // 2) on réclame au noyau l'utilisation du port passé en paramètre
     147        // INADDR_ANY dit que la socket va être affectée à toutes les interfaces locales
     148
     149        bzero((char *) &serv_addr, sizeof(serv_addr));
     150        portno = atoi(argv[1]);
     151        serv_addr.sin_family = AF_INET;
     152        serv_addr.sin_addr.s_addr = INADDR_ANY;
     153        serv_addr.sin_port = htons(portno);
     154        if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
     155                error("ERROR on binding");
     156
     157
     158        // On commence à écouter sur la socket. Le 5 est le nombre max
     159        // de connexions pendantes
     160
     161        listen(sockfd, 5);
     162        while (1) {
     163                newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
     164                if (newsockfd < 0)
     165                    error("ERROR on accept");
     166
     167                bzero(buffer, 256);
     168                n = read(newsockfd, buffer, 255);
     169                if (n < 0)
     170                    error("ERROR reading from socket");
     171
     172                printf("Received packet from %s:%d\nData: [%s]\n\n",
     173                       inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port),
     174                       buffer);
     175
     176                close(newsockfd);
     177        }
     178
     179        close(sockfd);
     180        return 0;
     181}
     182}}}
     183