Introduction aux réseaux IP, tutoriel & guide de travaux pratiques en pdf.
Les principales fonctions pour les sockets
Création d’une socket : socket() Cette fonction permet la création d’une socket
#include <sys/socket.h> int socket(int domain, int type, int protocol);
Paramètres : • domain : pour des sockets Internet, toujours donner la valeur AF_INET • type : SOCK_STREAM pour TCP ou SOCK_DGRAM pour UDP • protocol : toujours à 0 (en fait dépend de la valeur donnée pour type)
Valeur de retour : numéro de socket. Valeur égale –1 en cas d’erreur.
Par rapport à la connexion future cette primitive ne fait que donner le premier élément du quintuplet : {protocole, port source, adresse IP source, port dest, adesse IP dest}
Communiquer à travers un port : bind() Cette fonction permet d’associer une socket à un port source et une adresse IP source afin de pouvoir échanger avec une machine cible.
#include <sys/socket.h> int bind(int socketfd, struct sockaddr * addr, int addrlen);
Paramètres : • socketfd : descripteur de socket à savoir la valeur retournée par socket()
• addr : pointeur sur une structure struct sockaddr contenant notamment le numéro du port sur lequel le système doit écouter les demandes de connexion
• addrlen : taille de la structure qui vient d’être donnée en paramètre
Valeur de retour : 0 en cas de réussite. Sinon –1 en cas d’erreur.
Remarques : Dans beaucoup d’application (notament dans la programmation des clients), on a pas besoin de s’inquiéter du numéro de port, le protocole sous-jacent s’occupe de choisir un numéro de port pour l’application. On n’a donc pas besoin d’utiliser bind() pour la programmation client. En général, les serveurs ont des numéros de port bien connus du système. Bind() dit au système « c’est mon adresse, tout message reçu à cette adresse doit m’être envoyé ».
Cet appel système complète l’adresse locale et le numéro de port du quintuplet qui qualifie la connexion : {protocole, port source, adresse IP source, port dest, adesse IP dest}
Se connecter : connect() Cette fonction permet de réaliser une connexion TCP avec une machine cible.
#include <sys/socket.h> int connect(int socketfd, struct sockaddr * destAddr, int addrlen);
Les paramètres sont identiques à la fonction bind() en dehors du fait que destAddr contient l’adresse et le port de la machine cible.
Le quintuplet est maintenant complet : {protocole, port source, adresse IP source, port dest, adesse IP dest}
Ecouter les demandes de connexion : listen() Cette fonction permet de configurer les demandes de connexion. C’est-à-dire de préciser une taille de file d’attente pour les connexion à venir, lié à la socket créer précédement. Cette fonction marche généralement avec les sockets de type SOCK_STREAM.
#include <sys/socket.h> int listen(int socketfd, int backlog);
Paramètres : • socketfd : descripteur de socket à savoir la valeur retournée par socket() • backlog : taille de la file d’attente
Valeur de retour : 0 en cas de réussite. Sinon –1 en cas d’erreur.
Accepter une connexion : accept() Il s’agit d’une fonction bloquante qui ne rendra la main que lorsqu’une demande de connexion est réellement reçue. Cette fonction accepte une demande de connexion et ouvre une socket pour que la communication puisse se faire.
#include <sys/socket.h> int accept(int socketfd, struct sockaddr * addr, unsigned int * addrlen);
Paramètres : • socketfd : descripteur de socket à savoir la valeur retournée par socket() • addr : un pointeur sur une structure struct sockaddr_in qui va contenir les informations concernant l’appelant. Ceci est donc une nouvelle structure différente que de celle de la configuration du serveur. Cette structure vierge sera remplie par la fonction accept avec les informations de l’appelant. • addrlen : pointeur sur une variable entière initialisée avec sizeof(struct sockaddr_in). Si en retour cette valeur est modifiée, c’est que tous les champs n’ont pas été renseignés.
Valeur de retour : descripteur de la nouvelle socket. Sinon –1 en cas d’erreur. C’est ce descripteur qui sera utilisé par la suite pour toute communication avec le nouvel interlocuteur.
Echanger des données en mode connecté : send() et recv() Ces fonctions servent à envoyer et à recevoir des données à travers des sockets de type SOCK_STREAM.
#include <sys/socket.h> int send(int socketfd, void * data, int length, unsigned int flags); int recv(int socketfd, void * data, int length, unsigned int flags);
Paramètres : • socketfd : descripteur de socket à savoir la valeur retournée par socket() • data : un pointeur sur la zone devant contenir ou recevoir les données. • length : taille maximale de la zone contenant ou recevant les données. • flags : options paramétrant la réception ou l’envoie de données (en général 0).
Valeur de retour : nombre d’octets réellement envoyés ou reçus. Sinon –1 en cas d’erreur. Dans le cas de la fonction recv(), ce nombre peut également être 0 ce qui signifie en général que la connexion a été rompue ou qu’un problème est apparu.
Echanger des données en mode non connecté : sendto() et recvfrom() Ces fonctions sont identiques aux précédentes en dehors du fait qu’elles concernent les sockets de type SOCK_DGRAM et qu’elles prennent deux paramètres supplémentaires permettant d’identifier le correspondant.
#include <sys/socket.h> int sendto(int socketfd, void * data, int length, unsigned int flags, struct sockaddr * toaddr, int addrlen); int recvfrom(int socketfd, void * data, int length, unsigned int flags, struct sockaddr * fromaddr, int addrlen);
Paramètres et Valeur de retour : cf accept(), send() et recv()