Poignée de main (3 temps)
Poignée de main (2 temps)
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.
- 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.
- send et recv en mode connecté (TCP)
- sendto et recvfrom en mode non-connecté (UDP)
Serveur itératif
Serveur parallèle
Serveur itératif
Serveur parallèle
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.
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
Transcodage du format d'adresse
#include <arpa/inet.h> uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); in_addr inet_addr(const char *cp);
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);
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.
É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.
Fermeture de socket
#include <unistd.h> int close(int descripteur);
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"); } }
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); } }
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); }}
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); } }
Space | Forward |
---|---|
Left, Down, Page Down | Next slide |
Right, Up, Page Up | Previous slide |
P | Open presenter console |
H | Toggle this help |