L2 informatique Introduction aux réseaux : Programmation client
Transcription
L2 informatique Introduction aux réseaux : Programmation client
Les fonctions pour les sockets TCP UDP L2 informatique Introduction aux réseaux : Programmation client-serveur en C Sovanna Tan mars 2010 1/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmatio Les fonctions pour les sockets TCP UDP Plan 2/32 1 Les fonctions pour les sockets 2 TCP 3 UDP Sovanna Tan L2 informatique Introduction aux réseaux : Programmatio Les fonctions pour les sockets TCP UDP Sources Internetworking with TCP/IP volume 3 : Client-Server Programming and Applications, Douglas E. Commer and David L. Stevens, Prentice-Hall, 1993. Power Programming with RPC, John Bloomer, O’Reilly, 1992. http://www.commentcamarche.net/contents/sockets/ sockintro.php3 3/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmatio Les fonctions pour les sockets 4/32 TCP 1 Les fonctions pour les sockets 2 TCP 3 UDP Sovanna Tan UDP L2 informatique Introduction aux réseaux : Programmatio Les fonctions pour les sockets TCP UDP socket – close Création d’un socket int socket(int domain,int type,int protocol); domain : AF_INET pour Internet IPV4 type : SOCK_STREAM : TCP SOCK_DGRAM : UDP protocol : O pour IP, valeurs définies dans /etc/protocols Valeur de retour : descripteur de fichier du socket Fermeture d’un socket int close(int fd); fd : descripteur de fichier du socket 5/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmatio Les fonctions pour les sockets TCP UDP bind Lien du socket avec une adresse IP et un port struct sockaddr_in { short sin_family; /* must be AF_INET */ u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); sockfd : descripteur de fichier du socket addr : structure contenant les paramètres de connexion addrlen : longueur de la structure utilisée pour addr 6/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmatio Les fonctions pour les sockets TCP UDP listen – accept Mettre un socket en attente de connexion (mode passif) int listen(int sockfd, int backlog); sockfd : descripteur de fichier du socket backlog : longueur maximale de la queue pour les connexions en attente Autoriser les demandes de connexion int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); sockfd : descripteur de fichier du socket addr : structure contenant les paramètres de connexion addrlen : longueur de la structure utilisée pour addr Valeur de retour : nouveau descripteur de fichier pour le socket qui accepte les connexions 7/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmatio Les fonctions pour les sockets TCP UDP getsockname – connect Obtenir un pointeur sur la structure adresse liée au socket int getsockname(int s, struct sockaddr *name, socklen_t *namelen); s : descripteur de fichier du socket name : structure contenant les paramètres de connexion namelen : longueur de la structure utilisée pour addr Demande de connexion à un serveur int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); sockfd : descripteur de fichier du socket serv_addr : structure contenant l’adresse du serveur addrlen : longueur de la structure utilisée pour serv_addr 8/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmatio Les fonctions pour les sockets TCP UDP gethostbyname – gethostbyaddr : obtenir des informations réseau sur une machine 9/32 Obtenir des informations réseau sur une machine struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses */ }; struct hostent *gethostbyname(const char *name); struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type); name : nom ou adresse IPV4 addr : structure contenant l’adresse len : longueur de la structure type : type de la structure AF_INET ou AF_INET6 Sovanna Tan L2 informatique Introduction aux réseaux : Programmatio Les fonctions pour les sockets TCP UDP read – write Lecture/Ecriture de données en mode connecté ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); fd : descripteur de fichier du socket buf : pointeur sur le buffer count : nombre maximal d’octets à lire/écrire Valeur de retour : nombre d’octets lus/écrits 10/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP recvfrom – sendto Lecture/Ecriture de données en mode datagramme ssize_t sendto(int s,const void *buf,size_t len, int flags,const struct sockaddr *to,socklen_t tolen); ssize_t recvfrom(int s,void *buf,size_t len, int flags,struct sockaddr *from,socklen_t *fromlen); s : descripteur de fichier du socket buf : pointeur sur le buffer t : nombre d’octets du buffer flags : OU exclusif de drapeaux to/from : adresse du socket destination/source tolen/fromlen : taille de l’adresse du socket source/destination Valeur de retour : nombre d’octets lus/écrits 11/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP htons – inet ntoa Changer l’ordre des octets uint16_t htons(uint16_t hostshort); Convertit l’ordre des octets de Least Significant Byte First (octet de poids faible d’abord) utilisé sur l’hôte vers Most Significant Byte First (octet de poids fort d’abord) utilisé dans les réseaux. Obtenir une adresse IP sous forme décimale char *inet_ntoa(struct in_addr in); in : structure contenant l’adresse Valeur de retour : chaı̂ne de caractères contenant l’adresse notée avec des entiers en base 10 et des points 12/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets 13/32 TCP 1 Les fonctions pour les sockets 2 TCP 3 UDP Sovanna Tan UDP L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Programmer les sockets TCP Image provenant de http://www.tenouk.com/Module39a.html 14/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur TCP avec fork : serv.c (1) #include #include #include #include #include #include #include <stdio.h> <stdlib.h> <string.h> <sys/types.h> <sys/socket.h> <netinet/in.h> <netdb.h> #define BUFSZ 100 int main(int argc, char *argv[]) { struct sockaddr_in sin, from; struct sockaddr_in *ptr; struct sockaddr addr; int s,g; int len=sizeof(from); char diagbuf[BUFSZ]; int addrlen=sizeof(addr); 15/32 Sovanna Tan /* adresse de sockets internet */ /* adresse de socket generique */ /* descripteur de socket */ /* buffer de dialogue */ L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur TCP avec fork : serv.c (2) int rc; int NbAppel =0; int NbByte =0; /* compteur /* nombre d’octets recus */ */ bzero((char*) &sin, sizeof(sin)); sin.sin_family=AF_INET; /* domaine internet */ sin.sin_addr.s_addr=INADDR_ANY; sin.sin_port=0; /* accepte tous les clients */ /* systeme donne un port libre */ if((s=socket(AF_INET, SOCK_STREAM, 0))<0){ perror("socket"); exit(3); } if(bind(s,(struct sockaddr *)&sin,sizeof(sin)) <0){ perror("Erreur de bind\n"); exit(6); } 16/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur TCP avec fork : serv.c (3) if((rc=getsockname(s, &addr , &addrlen)) <0){ perror("Erreur socket\n"); exit(7); } ptr=(struct sockaddr_in *) &addr; printf("On m’a assigne le port %d\n",htons(ptr->sin_port)); listen(s,5); printf("Attente de demande de connexion\n"); while(1){ g=accept(s,(struct sockaddr *)&from,&len); NbAppel++;; printf("Connexion etablie canal %d, appel no %d\n",g,NbAppel); if(g<0){ perror("accept"); continue; } 17/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur TCP avec fork : serv.c (4) switch(fork()){ case -1: perror("fork echoue\n"); exit(4); case 0: close(s); printf("Debut du processus serveur pour l’appel %d\n",NbAppel); sprintf(diagbuf,"Appel no %d\n",NbAppel); write(g,diagbuf,strlen(diagbuf)); while(NbByte=read(g,diagbuf,BUFSZ-1)){ printf("De l’appel no %d: %s (long %d)\n",NbAppel,diagbuf, strlen(diagbuf)); bzero(diagbuf,BUFSZ); } printf("Fin du processus serveur pour l’appel %d\n",NbAppel); close(g); exit(0); default: ; } } } 18/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur TCP avec select : selserv.c (1) #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define BUFSZ 1024 /* fonction pour lire le message d’un client */ char *lire_message(int sock) { char *msg = (char *)malloc(BUFSZ * sizeof(char)); int nb_lu; nb_lu = read(sock, msg, BUFSZ); if(nb_lu >2){ /* message non vide */ printf("De l’appel no %d: %s (long %ld)\n", sock, msg,strlen(msg)+1); fflush(stdout); return msg; } else return NULL; } 19/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur TCP avec select : selserv.c (2) int main(int argc, char *argv[]) { struct sockaddr_in sin, from; struct sockaddr_in *ptr; struct sockaddr addr; int s,g,fd,c; int len=sizeof(from); char diagbuf[BUFSZ]; char accueil[BUFSZ]; int addrlen=sizeof(addr); int rc; int NbAppel =0; bzero((char*) &sin, sizeof(sin)); sin.sin_family=AF_INET; sin.sin_addr.s_addr=INADDR_ANY; sin.sin_port=0; char *message; fd_set rfds, afds; int nfds; 20/32 /* adresse de sockets internet */ /* adresse de socket generique */ /* descripteur de socket */ /* buffer de dialogue /* buffer de dialogue */ */ /* compteur */ /* domaine internet */ /* accepte tous les clients */ /* systeme donne un port libre */ /* rfds est la liste des clients */ /* nfds est la taille de la liste*/ Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur TCP avec select : selserv.c (3) if((s=socket(AF_INET, SOCK_STREAM, 0))<0){ perror("socket"); exit(3); } if(bind(s,(struct sockaddr *)&sin,sizeof(sin)) <0){ perror("Erreur de bind\n"); exit(6); } if((rc=getsockname(s, &addr , &addrlen)) <0){ perror("Erreur socket\n"); exit(7); } ptr=(struct sockaddr_in *) &addr; printf("On m’a assigne le port %d\n",htons(ptr->sin_port)); listen(s,5); /* initialise liste des clients */ nfds = getdtablesize(); FD_ZERO(&afds); FD_SET(s, & afds); /* fd_set sert a ajouter un element a la liste */ printf("Initialisation complete\n"); 21/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur TCP avec select : selserv.c (4) /* gestion des clients */ while(1){ memcpy(&rfds, &afds, sizeof(rfds)); select(nfds, & rfds, 0, 0, 0); if( FD_ISSET(s, &rfds) ){ /*fd_isset sert a tester si la liste est vide*/ /* connexion d’un client */ g=accept(s,(struct sockaddr *)&from,&len); NbAppel++;; printf("Connexion etablie canal %d, appel no %d\n",g,NbAppel); /* ajout du client dans la liste des clients */ FD_SET(g, &afds); sprintf(accueil,"Vous etes connecte sur le canal no %d. \nEcrivez un message vide (appui sur la touche Entree) pour vous deconnecter.\n", g); write(g,accueil, strlen(accueil)+1); } /* lit le message du client et l’envoie a tout le monde */ for( fd=0; fd<nfds; fd++ ) if( fd != s && FD_ISSET(fd, &rfds) ) { if( (message = lire_message(fd)) != NULL ) { 22/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur TCP avec select : selserv.c (5) for( c=0; c<nfds; c++){ if( c!=s && FD_ISSET(c, &afds) ){ sprintf(diagbuf,"Message du canal %d : ", fd); strcat(diagbuf,message); write(c, diagbuf, strlen(diagbuf)+1); } } } else{ close(fd); FD_CLR(fd, &afds); printf("\nDeconnexion sur le canal %d.\n\n", fd); } } } } 23/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Client TCP : clie.c (1) #include <stdio.h> include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define BUFSZ 100 int main(int argc, char *argv[]) { struct sockaddr_in sin, pin; struct hostent *hp; int s; char diagbuf[BUFSZ]; if((hp=gethostbyname(argv[1]))==0){ perror("gethostbyname"); exit(1); } bzero((char*) &pin, sizeof(pin)); pin.sin_family=AF_INET; 24/32 Sovanna Tan /* /* /* /* adresse de sockets internet adresse du serveur descripteur de socket buffer de dialogue */ */ */ */ L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Client TCP : clie.c (2) pin.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr; pin.sin_port=htons(atoi(argv[2])); if((s=socket(PF_INET, SOCK_STREAM, 0))<0){ perror("socket"); exit(1); } if(connect(s,(struct sockaddr *) &pin,sizeof(pin)) == -1){ perror("connect"); exit(1); } bzero(diagbuf,BUFSZ); read(s,diagbuf,BUFSZ-1); printf("%s (long %d)\n",diagbuf,strlen(diagbuf)); bzero(diagbuf,BUFSZ); sprintf(diagbuf,"Je suis un client\n"); write(s,diagbuf,strlen(diagbuf)); bzero(diagbuf,BUFSZ); sprintf(diagbuf,"Bye\n"); write(s,diagbuf,strlen(diagbuf)); close(s); } 25/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets 26/32 TCP 1 Les fonctions pour les sockets 2 TCP 3 UDP Sovanna Tan UDP L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Programmer les sockets UDP Image provenant de http://www.tenouk.com/Module39a.html 27/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur UDP : userv.c (1) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define BUFSZ 100 int main(int argc, char *argv[]) { struct sockaddr_in sin; struct sockaddr_in *ptr; struct sockaddr addr,from; int s,g; int fromlen=sizeof(from); char diagbuf[BUFSZ]; int addrlen=sizeof(addr); struct hostent *hp, *gethostbyaddr(); int rc; int NbAppel =0; int NbByte =0; 28/32 Sovanna Tan /* adresse de sockets internet */ /* adresse de socket generique */ /* descripteur de socket */ /* buffer de dialogue */ /* compteur /* nombre d’octets recus */ */ L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur UDP : userv.c (2) bzero((char*) &sin, sizeof(sin)); sin.sin_family=AF_INET; /* domaine internet sin.sin_addr.s_addr=INADDR_ANY; sin.sin_port=0; /* accepte tous les clients */ /* systeme donne un port libre */ */ if((s=socket(AF_INET, SOCK_DGRAM, 0))<0){ perror("socket"); exit(3); } if(bind(s,(struct sockaddr *)&sin,sizeof(sin)) <0){ perror("Erreur de bind\n"); exit(6); } if((rc=getsockname(s, &addr , &addrlen)) <0){ perror("Erreur socket\n"); exit(7); } 29/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Serveur UDP : userv.c (3) ptr=(struct sockaddr_in *) &addr; printf("On m’a assigne le port %d\n",htons(ptr->sin_port)); bzero(diagbuf,BUFSZ); while(NbByte=recvfrom(s,diagbuf,BUFSZ-1,0,&from,&fromlen)){ ptr=(struct sockaddr_in *) &from; if(hp=gethostbyaddr((char *)&ptr->sin_addr,4,AF_INET)){ printf("From host: %s ",hp->h_name); printf("From host: %s ", inet_ntoa(ptr->sin_addr)); } else printf("From host: %s ", inet_ntoa(ptr->sin_addr)); printf("From port: %d\n", htons(ptr->sin_port)); printf("Received: %s\n",diagbuf); bzero(diagbuf,BUFSZ); sprintf(diagbuf,"Recu"); sendto(s,diagbuf,4,0, &from,sizeof(sin)); bzero(diagbuf,BUFSZ); } } 30/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Client UDP : uclie.c (1) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define BUFSZ 100 int main(int argc, char *argv[]) { struct sockaddr_in sin, pin; struct sockaddr addr,from; int fromlen=sizeof(from); struct hostent *hp; int s; char diagbuf[BUFSZ]; int i; /* adresse de sockets internet */ /* adresse du serveur /* descripteur de socket /* buffer de dialogue */ */ */ if((hp=gethostbyname(argv[1]))==0){ perror("gethostbyname"); exit(1); } 31/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat Les fonctions pour les sockets TCP UDP Client UDP : uclie.c (2) bzero((char*) &pin, sizeof(pin)); pin.sin_family=AF_INET; pin.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr; pin.sin_port=htons(atoi(argv[2])); if((s=socket(AF_INET, SOCK_DGRAM, 0))<0){ perror("socket"); exit(1); } bzero(diagbuf,BUFSZ); for(i=0;i<100;i++){ sprintf(diagbuf,"Coucou"); sendto(s,diagbuf,6,0, (struct sockaddr *) &pin,sizeof(pin)); bzero(diagbuf,BUFSZ); recvfrom(s,diagbuf,BUFSZ-1,0,&from,&fromlen); } printf("%s fin \n",diagbuf); close(s); } 32/32 Sovanna Tan L2 informatique Introduction aux réseaux : Programmat