diff --git a/client_echo.c b/client_echo.c index 01df744..92faf73 100755 --- a/client_echo.c +++ b/client_echo.c @@ -1,96 +1,92 @@ +#include +#include +#include #include #include -#include #include -#include -#include -#include -#include -#include - -#define LG_BUFFER 1024 - -int main (int argc, char * argv[]) { - struct sockaddr_in adresse; - int sock; - - char buffer [LG_BUFFER]; - int nb_lus; - - if (argc != 3){ - perror("Nombre d'arguments invalides, vous devez entrer deux arguments"); - exit(-1); - } - - - // Serveur auquel on se connecte - //char * hote = "127.0.0.1"; - char * hote = argv[1]; - - // Port du serveur sur lequel on se connecte0 - //int port = 1234; - int port = atoi(argv[2]); - - struct hostent * hostent; - struct servent * servent; - - // Vider la structure adresse - memset(&adresse, 0, sizeof(struct sockaddr_in)); - - // Donner l'adresse du serveur à la structure adresse - if (inet_aton(hote, & (adresse.sin_addr)) == 0) { - if ((hostent = gethostbyname(hote)) == NULL) { - printf("Erreur : hote %s inconnu \n", hote); - return -1; - } - adresse.sin_addr.s_addr = ((struct in_addr *) (hostent->h_addr))->s_addr; - } - - // Donner un numero de port à la structure adresse - adresse.sin_port = htons(port); - - // Donner la famille de socket à la structure adresse - adresse.sin_family = AF_INET; - - // Créer la socket nommée sock - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { - printf("Erreur : socket\n"); - exit(EXIT_FAILURE); - } - - // Etablir la connexion avec le serveur - if(connect(sock, (struct sockaddr *) & adresse, sizeof (struct sockaddr_in)) < 0 ) { - printf("Erreur : socket"); - return -1; - } - - while (1) { - // Lecture du clavier - if (fgets(buffer, 256, stdin) == NULL) - break; - - if (buffer[strlen(buffer) - 1] == '\n') - buffer[strlen(buffer) - 1] = '\0'; - - // Ecriture des données sur la socket - if (write(sock, buffer, strlen(buffer)) < 0 ) { - printf("Erreur : write\n"); - break; - } - - // Lecture de la réponse du serveur - if ((nb_lus = read(sock, buffer, LG_BUFFER)) == 0 ) { - break; - } - - if (nb_lus < 0) { - printf("Erreur : read\n"); - break; - } - - // Affichage de données recues, variable buffer - printf("%s\n", buffer); - } +#include - return EXIT_SUCCESS; +#define BUF_SIZE 500 + +int +main(int argc, char *argv[]) +{ + struct addrinfo hints; + struct addrinfo *result, *rp; + int sfd, s, j; + size_t len; + ssize_t nread; + char buf[BUF_SIZE]; + + if (argc < 3) { + fprintf(stderr, "Usage: %s host port msg...\n", argv[0]); + exit(EXIT_FAILURE); + } + + /* Obtain address(es) matching host/port */ + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ + hints.ai_flags = 0; + hints.ai_protocol = 0; /* Any protocol */ + + s = getaddrinfo(argv[1], argv[2], &hints, &result); + if (s != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + exit(EXIT_FAILURE); + } + + /* getaddrinfo() returns a list of address structures. + Try each address until we successfully connect(2). + If socket(2) (or connect(2)) fails, we (close the socket + and) try the next address. */ + + for (rp = result; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, + rp->ai_protocol); + if (sfd == -1) + continue; + + if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; /* Success */ + + close(sfd); + } + + if (rp == NULL) { /* No address succeeded */ + fprintf(stderr, "Could not connect\n"); + exit(EXIT_FAILURE); + } + + freeaddrinfo(result); /* No longer needed */ + + /* Send remaining command-line arguments as separate + datagrams, and read responses from server */ + + for (j = 3; j < argc; j++) { + len = strlen(argv[j]) + 1; + /* +1 for terminating null byte */ + + if (len + 1 > BUF_SIZE) { + fprintf(stderr, + "Ignoring long message in argument %d\n", j); + continue; + } + + if (write(sfd, argv[j], len) != len) { + fprintf(stderr, "partial/failed write\n"); + exit(EXIT_FAILURE); + } + + nread = read(sfd, buf, BUF_SIZE); + if (nread == -1) { + perror("read"); + exit(EXIT_FAILURE); + } + + printf("Received %ld bytes: %s\n", (long) nread, buf); + } + + exit(EXIT_SUCCESS); } diff --git a/client_echo.o b/client_echo.o index 1f54f4b..36d1a3d 100755 Binary files a/client_echo.o and b/client_echo.o differ diff --git a/serveur_echo.c b/serveur_echo.c index fe9ea6e..2781ce3 100755 --- a/serveur_echo.c +++ b/serveur_echo.c @@ -1,168 +1,91 @@ -#define _GNU_SOURCE +#include #include #include -#include #include -#include -#include -#include -#include +#include #include +#include -int cree_socket_stream (const char * nom_hote, const int num_port, const char * nom_proto); -int affiche_adresse_socket (int sock); -int serveur_tcp (void); -void traite_connexion (int sock); - -int cree_socket_stream (const char * nom_hote, const int num_port, const char * nom_proto){ - int sock; - struct sockaddr_in adresse; - struct hostent * hostent = NULL; - struct protoent * protoent = NULL; - - if (nom_hote != NULL) { - if ((hostent = gethostbyname(nom_hote)) == NULL) { - printf("Erreur : gethostbyname\n"); - return -1; - } - } - - if ((protoent = getprotobyname(nom_proto)) == NULL) { - printf("Erreur : getprotobyname\n"); - return -1; - } - - // Créer la socket nommée sock - if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { - printf("Erreur : socket"); - return -1; - } - - // Mise à 0 de la structure adresse - memset(& adresse, 0, sizeof(struct sockaddr_in)); - - // Donner la famille de socket dans la structure adresse - adresse.sin_family = AF_INET; - - adresse.sin_port = num_port; - - // Donner un numero de port à la structure adresse - if (num_port > 1024) { - adresse.sin_port = htons(num_port); - } - else { - adresse.sin_port = htons(0); - } - - // Donner l'adresse du serveur à la structure adresse - if (hostent != NULL) { - adresse.sin_addr.s_addr = ((struct in_addr *) (hostent->h_addr))->s_addr; - } - else { - adresse.sin_addr.s_addr = htonl(INADDR_ANY); - } - // Pattacher un port a la socket sock - if (bind(sock, (struct sockaddr *) & adresse, sizeof(struct sockaddr_in)) < 0) { - close(sock); - printf("Erreur : bind\n"); - return -1; - } - return sock; -} - -int affiche_adresse_socket (int sock) { - struct sockaddr_in adresse; - socklen_t longueur; - - longueur = sizeof(struct sockaddr_in); - - if (getsockname(sock, & adresse, & longueur) < 0) { - printf("Erreur : getsockname\n"); - return -1; - } - printf ("IP = %s, Port = %u \n", inet_ntoa(adresse.sin_addr), ntohs(adresse.sin_port)); - return 0; -} - -int serveur_tcp (void) { - int sock_contact; // Socket créée du côté du serveur - int sock_connectee; // Socket du côté du client qui se connecte - struct sockaddr_in adresse; - socklen_t longueur; - - longueur = sizeof(struct sockaddr_in); - - // Appeler la fonction cree_socket_stream() pour créer la socket nommée socket_contact - // Choisir : nom de l'hote, le num du port, le protocole - - sock_contact = cree_socket_stream("0.0.0.0", 1234, "tcp"); - - if (sock_contact < 0) { - return -1; - } - - // Placer le serveur en écoute sur la socket nommée sock_contact - listen(sock_contact, 5); - - printf("Mon adresse >> "); - affiche_adresse_socket(sock_contact); - - while (1) { - // tester si un client se connecte : appel accept() bloquant - // Le retour de accept() est une nouvelle socket nommé sock_connectee - // avec laquelle l'échange avec le client aura lieu - - sock_connectee = accept(sock_contact, & adresse, & longueur); - - if (sock_connectee < 0) { - printf("Erreur : accept\n"); - return -1; - } - - printf("Nouveau client\n"); - - switch (fork()) { - case 0 : // Code du fils - close(sock_contact); - traite_connexion(sock_connectee); - exit(EXIT_SUCCESS); - case -1 : - printf("Erreur : fork\n"); - return -1; - default : // Code du pere - close(sock_connectee); - } - } - return 0; -} - -void traite_connexion (int sock){ - char buffer[256]; - int longueur; - - while (1) { - // Lire la socket et récupérer le nombre d'octets lus dans la variable longueur - longueur = read(sock, buffer, 256); - - if (longueur < 0) { - printf("Erreur : read\n"); - exit(EXIT_SUCCESS); - } - - if (longueur == 0) { - break; - } - - printf("J'ai lu %d bytes\n",longueur); - // Pour le client telnet : - //buffer[longueur-2] = '\0'; - - // Ecrire la variable buffer sur la socket - write(sock, buffer, longueur); - } - close(sock); -} - -int main (int argc, char * argv[]) { - return serveur_tcp(); +#define BUF_SIZE 500 + +int +main(int argc, char *argv[]) +{ + struct addrinfo hints; + struct addrinfo *result, *rp; + int sfd, s; + struct sockaddr_storage peer_addr; + socklen_t peer_addr_len; + ssize_t nread; + char buf[BUF_SIZE]; + + if (argc != 2) { + fprintf(stderr, "Usage: %s port\n", argv[0]); + exit(EXIT_FAILURE); + } + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ + hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ + hints.ai_protocol = 0; /* Any protocol */ + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + s = getaddrinfo(NULL, argv[1], &hints, &result); + if (s != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + exit(EXIT_FAILURE); + } + + /* getaddrinfo() returns a list of address structures. + Try each address until we successfully bind(2). + If socket() (or bind()) fails, we (close the socket + and) try the next address. */ + + for (rp = result; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, + rp->ai_protocol); + if (sfd == -1) + continue; + + if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) + break; /* Success */ + + close(sfd); + } + + if (rp == NULL) { /* No address succeeded */ + fprintf(stderr, "Could not bind\n"); + exit(EXIT_FAILURE); + } + + freeaddrinfo(result); /* No longer needed */ + + /* Read datagrams and echo them back to sender */ + + for (;;) { + peer_addr_len = sizeof(struct sockaddr_storage); + nread = recvfrom(sfd, buf, BUF_SIZE, 0, + (struct sockaddr *) &peer_addr, &peer_addr_len); + if (nread == -1) + continue; /* Ignore failed request */ + + char host[NI_MAXHOST], service[NI_MAXSERV]; + + s = getnameinfo((struct sockaddr *) &peer_addr, + peer_addr_len, host, NI_MAXHOST, + service, NI_MAXSERV, NI_NUMERICSERV); + if (s == 0) + printf("Received %ld bytes from %s:%s\n", + (long) nread, host, service); + else + fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s)); + + if (sendto(sfd, buf, nread, 0, + (struct sockaddr *) &peer_addr, + peer_addr_len) != nread) + fprintf(stderr, "Error sending response\n"); + } } diff --git a/serveur_echo.o b/serveur_echo.o index a7a9192..c704383 100755 Binary files a/serveur_echo.o and b/serveur_echo.o differ