La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

1 Les sockets UNIX Sylvie Dupuy année 2000.

Présentations similaires


Présentation au sujet: "1 Les sockets UNIX Sylvie Dupuy année 2000."— Transcription de la présentation:

1 1 Les sockets UNIX Sylvie Dupuy année 2000

2 2 Protocoles de lInternet : rappels Interface du service de transport PHY 1 PHY 2 ARP MAC 1 MAC 2 Data Link 1 MAC 1 MAC 2 Data Link 2 Data Link 1 ARP ICMP IP ICMP IP ICMPTCPUDP TCP Num. port UDP ou TCP APPLICATION Numéro de port = identifie lapplication à laquelle le paquet IP est destiné send receive Routeur IP Endsystem sur réseau 1Endsystem sur réseau 2

3 3 Notion de socket (1) Permet détablir un canal de communication bidirectionnel entre deux applications (plus exactement entre deux TSAPs) Socket UDP : paquets de taille variable, transport non fiable (pertes, duplications, erreurs possibles) Socket TCP : paquets de taille variable délivrés dans lordre et sans erreurs => Choisir le protocole en fonction des besoins de lapplication : données informatiques (FTP, Telnet) : TCP, video : UDP

4 4 Notion de socket (2) Sous Unix les applications sont dénommées processus Les processus actifs sont répertoriées dans une table du système et identifiés par un pid (cf. commande ps) Lorsquil est actif, un processus possède un contexte dexécution => variables denvironnement, table de descripteurs de fichiers ouverts …

5 5 Notion de socket (3) Mécanisme de communication entre applications sous Unix : - pipe (ou tube nommé) -> fichier - mémoire partagée (system V) - file de messages - sockets Lorsquun objet de ce type est créé par une application, le système lui alloue un identifiant. Lidentifiant dun socket est un descripteur analogue aux descripteurs de fichiers.

6 6 Fork et héritage Unix est un système multitâches : => un processus en cours dexécution peut se dupliquer dynamiquement : fork() => après un fork(), deux applications : le processus père et le processus fils sexécutent simultanément (en temps partagé ou bien en parallèle sur un système multiprocesseurs) => le processus fils hérite du contexte dexécution du processus père

7 7 Terminaison de processus Le processus père attend habituellement la terminaison du processus fils : => wait(), attente passive : reçoit le signal SIGCLD (cf. table des signaux /usr/include/signal.h) Lorsque le processus père se termine sans avoir fait un wait (), le processus fils est rattaché au processus de PID 1 (init)

8 8 Recouvrement Le code du processus fils peut être dynamiquement remplacé par celui dun exécutable stocké sur disque : => exec () Possibilité de passage de paramètres (ligne de commande) et des variables denvironnement Après un exec() le processus conserve toutes ses caractéristiques : PID, priorité, propriétaire et groupe réels, catalogue courant, terminal associé, masque de création de fichiers, descripteurs de fichiers ouverts, signaux ignorés (les autres signaux reprennent leur comportement par défaut)

9 9 Redirection des entrées/sorties Les descripteurs de fichiers 0,1 et 2 correspondent respectivement à : - lentrée standard (clavier), - la sortie standard (écran), - la sortie erreur standard (écran) Ces fichiers spéciaux (mode caractère) sont ouverts par défaut lors de la création du processus La primitive système dup() permet de dupliquer un descripteur (ie. Toutes les lectures/écritures effectuées sur lun des fichiers le sont aussi sur lautre) => par ce mécanime, les fichiers standards peuvent être redirigés

10 10 Modèle de communication Un processus (le serveur) est en attente (à lécoute) sur un numéro de port => tous les processus (les clients) connaissant ladresse IP du serveur et le numéro de port peuvent lui envoyer des messages (requêtes) Le serveur traîte les messages entrants puis renvoie une réponse au client en utilisant le numéro de port source contenu dans len-tête du message En mode connecté (TCP) il y a établissement préalable dune connexion

11 11 Programmation des sockets Les sockets sont identifiés dans le système par des descripteurs de même nature que les descripteurs de fichiers => les fichiers dentrées/sortie standard (desc. 0,1 et 2) peuvent être redirigés sur des sockets => il y a héritage des descripteurs de sockets après un fork() Le descripteur dun socket est renvoyé par la primitive socket(). Le processus peut alors effectuer des opérations de lecture/écriture car la communication est bidirectionnelle (!= tube) Les frontières de messages sont conservées

12 12 Domaine dun socket(1) Domaine UNIX : AF_UNIX Les sockets sont locales au système et fournissent un mécanisme dIPC (InterProcessus Communication) struct sockaddr_un { shortsun_family;/* AF_UNIX */ charsun_path [108]/* référence UNIX */ };

13 13 Domaine dun socket(2) Domaine internet : AF_INET struct in_addr { u_longs_addr; }; struct sockaddr_in { shortsin_family;/* AF_INET */ u_shortsin_port;/* numéro de port */ struct sin_addr;/* adresse internet */ char sin_zero[8];/* champ de 8 zeros] */ };

14 14 Types de sockets SOCK_DGRAM : transport de données en mode non connecté. Dans le domaine AF_INET, le protocole UDP est utilisé. Les frontières de messages sont préservées. SOCK_STREAM : transport de données en mode connecté. Dans le domaine AF_INET, utilisation de TCP. Frontières de messages préservées et possibilité denvoi de messages urgents. SOCK_RAW : permet laccès au service de niveau 3 (émission/réception de paquets IP) SOCK_SEQPACKET : comme le type SOCK_STREAM mais ne permettant pas lenvoi de messages urgents

15 15 Création dun socket int socket (domaine, type, protocole) int domaine;/* AF_INET, … */ int type;/* SOCK_DGRAM, … */ int protocole;/* 0 : protocole par défaut attribué par le système*/ Structure de données associée à un socket : type, domaine et protocole du socket état (en état de recevoir ou démettre) adresse des buffers de réception et démission pointeurs sur les données en émission/réception groupe de processus pour la gestion des signaux SIGURG, SIGIO

16 16 Binding : association socket/adresse int bind (sock, p_adresse, lg) int sock;/* descripteur de socket */ struct sockaddr *p_addresse; /* pointeur sur ladresse */ int lg; /* longueur de ladresse */ Après sa création un socket est accessible par son descripteur. Seuls des processus fils peuvent en hériter. Bind fournit un procédé de nommage dun socket permettant à dautres processus dy accèder. Cas derreurs : descripteur incorrect (EBADF,ENOTSOCK), adresse incorrecte, inaccessible ou déjà utilisée (EADDRNOTAVAIL, EADDRINUSE, EACCESS), socket déjà associé à une adresse (EINVAL).

17 17 Binding dans le domaine AF_INET(1) Dans le domaine internet, le champ sockaddr est une structure sockaddr_in => choisir une adresse internet quelconque (INADDR_ANY) ou spécifier ladresse dune interface IP (gethostname() et gethostbyname()) => choisir le numéro de port (getservbyname() dans le cas dun service existant) ou bien fixer un numéro non réservé (>= IPPORT_RESERVED) ou bien laisser le système choisir un numéro de port (initialiser le champ sin_port à zéro)

18 18 Binding dans le domaine AF_INET(2) Pour accéder à ladresse associée à un socket en connaissant seulement son descripteur : int getsockname (sock, p_adr, p_lg) int sock;/* descripteur du socket */ struct sockaddr_in *p_addr;/* pointeur sur ladresse */ int *p_lg; /* pointeur sur la longueur de ladresse */ A lappel p_lg = sizeof(struct sockaddr_in), au retour p_lg = longueur effective de ladresse

19 19 Emission de datagrammes(1) int sendto(sock, ms, lg, option, p_dest, lgdest) int sock;/* descripteur du socket */ char *msg;/* adresse du message à envoyer */ int lg;/* longueur du message */ int option;/* =0 pour le type SOCK_DGRAM */ struct sockaddr *p_dest;/* pointeur sur adresse socket dest */ int lgdest;/* longueur adresse socket dest */ => retour = nombre de caractères envoyés ou –1 en cas déchec (descripteur ou adresse du socket de destination invalide, taille de message ne permettant pas lenvoi dun seul datagramme)

20 20 Emission de datagrammes(2) Pour envoyer une série de messages : int sendmsg (sock, msg, option) int sock;/* descripteur du socket en émission */ struct msghdr msg[];/* tableau des en-têtes de messages */ int option; => cette primitive denvoi peut être utilisée sans appel préalable à la primitive bind(). Le système associe le socket à une adresse lors de lenvoi du premier message.

21 21 Emission de datagrammes(3) Structure des en-têtes de messages à émettre struct msghdr { caddr_tmsg_name;/* adresse optionnelle */ int msg_namelen;/* taille de ladresse */ struct iovec *msg_iov;/* tableau de messages */ int msg_iovlen;/* nombre délements du tableau */ caddr_tmsg_accrights;/* inutilisé pour les sockets */ int msg_accrightslen;/* inutilisé pour les sockets */ }; Structure iovec struct iovec { caddr_tiov_base;/* adresse du message */ int iov_len;/* longueur du message */ };

22 22 Réception de datagrammes (1) int recvfrom ( sock, msg, option, p_exp, p_lgexp) int sock;/* descripteur du socket */ char *msg;/* adresse mémoire du message reçu */ int lg; /* taille du buffer contenant le message */ int option;/* 0 ou MSG_PEEK*/ struct sockaddr *p_exp;/* adresse de lexpediteur */ int *p_lgexp;/* sizeof(p_exp) et longueur du résultat */ Le paramètre lg doit correspondre à la taille du message reçu, sinon des caractères sont perdus (il faut connaître la taille du message envoyé) Retourne le nombre de caractères reçus ou –1 en cas derreur

23 23 Réception de datagrammes (2) Lappel recvfrom est bloquant. Pour éviter lattente de réception dun message, utiliser fcntl ( sock, F_SETFL,FNDELAY|fcntl (sock, F_GETFL,0)); Pour répondre, le processus extrait ladresse et le numéro de port de la structure sockaddr (sockaddr_in dans le domaine AF_INET); Loption MSG_PEEK permet de consulter le message sans lextraire Pour recevoir une série de messages : int recvmsg ( sock, msg, option) int sock;/* descripteur du socket de réception */ struct msghdr [ ];/* tableau des en-têtes reçus */ int option;

24 24 Communication client/serveur(1) Sur le serveur : - créér un socket de type SOCK_DGRAM (donner un numéro de port) - détacher le serveur du terminal de lancement (pas dinterruptions clavier possibles) - boucler en attente des messages : les lire par recvfrom( ), y répondre par sendto( ) Sur le client : - récupérer ladresse du serveur (gethostbyname( )) - créer un socket, initialiser les champs (numéro de port, - envoyer une requête par sendto ( ), lire la réponse par recvfrom ( )

25 25 Communication client/serveur(2) Les fonctions suivantes sont utilisées pour la programmation des sockets : - bzero : initialiser à zéro les champs dune structure sockaddr - bcopy : initialiser le champ adresse (sin_addr) dune structure sockaddr - htons : initialiser le champ port de la structure (little != big endian) Pour éviter lattente active du serveur (while(1)), le service associé au numéro de port choisi pour le serveur peut être enregistré dans le fichier /etc/services. En modifiant le fichier /etc/inetd.conf, le processus daemon inetd prendra en charge la création dun processus serveur sur réception dun message de requête contenant le numéro de port du service (attente active, select, fork()). Inetd relit le fichier inetd.conf sur réception dun signal SIGHUP.

26 26 Communication en mode connecté(1) Linformation est échangée après établissement dune connexion. Contrairement à lémission de datagrammes, les messages sont reçus en mode flot (pas de notion de frontière de message) Modèle de communication : - le serveur est en attente dune demande de connexion sur un numéro de port TCP correspondant à un service via un socket. - lorsquune requête arrive le serveur reçoit un signal, il crée un nouveau socket puis se duplique (fork()). - le processus fils prend en charge léchange de données avec le client (exec()), tandis que le processus père retourne attendre de nouvelles demandes de connexion sur le premier socket.

27 27 Communication en mode connecté(2) Primitives associèes au différentes étapes de la communication : Création et attachement du socket Socket/bind Ouverture du service listen Attente de la demande de connexion accept Création dun processus fils fork processus père Traitement de la demande exec processus fils

28 28 Listen( ) Après avoir créé un socket de type SOCK_STREAM, le serveur indique au système quil est à lécoute sur un port TCP socket (AF_INET, SOCK_STREAM, 0); int listen ( sock, nb ) int sock;/* descripteur du socket découte */ int nb;/* nombre maxi de connexions */ => si le champ sin_port de la structure sockaddr_in na pas été initialisé, le numéro de port est attribué par le système. Le processus utilisera getsockname() pour le connaître

29 29 Accept() Accept() permet dextraire une demande de connexion parmi lensemble des requêtes en attente (FIFO) La primitive crée un nouveau socket qui est associée à un nouveau numéro de port choisi par le système et retourne son descripteur Au retour de lappel, le champ p_adr->sin_port contient le numéro de port du socket du client ayant demandé louverture dune connexion int accept ( sock, p_adr, p_lgadr ) int sock;/* descripteur du socket */ struct sockaddr *p_adr;/* adresse du socket */ int *p_lgadr;/* pointeur sur la longueur de ladresse */ => sil ny a pas de requête en attente lappel est bloquant sauf si le socket est en mode non bloquant (cf. fcntl). En ce cas, la valeur de retour vaut –1 et errno = EWOULDBLOCK

30 30 Communication en mode connecté : côté client Etapes dune demande détablissement de connexion : Création et attachement du socket Socket/bind Construction de ladresse du serveur Demande de connexion connect Echec Dialogue avec le serveur

31 31 Connect( ) La primitive connect() réalise létablissement dune connexion bidirectionnelle de bout-en-bout entre le client et le serveur en associant socket serveur et socket client. int connect ( sock, p_adr, lgadr ) int sock;/* descripteur socket local */ struct sockaddr *p_adr;/* adresse socket distant */ int lgadr;/* longueur adresse distante */ => socket local et distant doivent être de même type et appartenir au même domaine. => le serveur doit avoir effectué un listen() et ne pas avoir atteint la file de demandes de connexion en attente ne doit pas être pleine.

32 32 Connect( ) : délai détablissement dune connexion Lorsque la file de demandes de connexions du serveur est pleine, le processus client est bloqué jusquà expiration du délai détablissement dune connexion. Le code de retour est alors –1 et errno = ETIMEDOUT En mode non bloquant, le retour est immédiat mais la tentative détablissement de connexion est maintenue : - le client peut senquérir de létablissement de la connexion avec select( ) en passant le descripteur du socket parmi les paramètres représentant les descripteurs testés en écriture. - sil exécute à nouveau un connect avant expiration du délai détablissement, le retour est immédiat et errno = EALREADY

33 33 Emission/Réception de messages TCP(1) Les primitives standard de lecture/écriture de fichiers permettent de lire/écrire dans les sockets, donc denvoyer des messages TCP int write ( sock, msg, lg ) int sock;/* descripteur du socket local */ char *msg;/* adresse du message */ int lg;/* longueur du message */ int read ( sock, msg, lg ) int sock;/* descripteur du socket local */ char *msg;/* adresse de sauvegarde du message */ int lg;/* longueur de la zône */

34 34 Emission de messages TCP(2) La primitive send permet lenvoi de données urgentes (hors bande) int send (sock, msg, option) int sock;/* descripteur du socket local */ char *msg;/* adresse du message à envoyer */ int lg;/* longueur du message */ int option/* 0 ou MSG_OOB */ => retourne le nombre de caractères émis la lecture est bloquante si le buffer en émission (socket local) ou le buffer en réception (socket distant) est plein fcntl( ) permet les lectures non bloquantes

35 35 Réception de messages TCP(3) La primitive recv permet dextraire des données urgentes et de lire des données sans les extraire du buffer de réception du socket int recv ( sock, msg, lg, option ) int sock;/* descripteur du socket local */ char *msg;/* adresse de sauvegarde du message */ int lg;/* longueur de la zone */ int option;/* 0 ou MSG_PEEK ou MSG_OOB */ => La lecture est par défaut bloquante. Le paramètre lg spécifie un nombre maximal de caractères à lire.

36 36 Terminaison dune connexion Au lieu dutiliser la primitive close sur le descripteur du fichier comme pour les sockets UDP, il faut utiliser la primitive shutdown qui assure le transfert des messages en attente démission dans les buffers locaux int shutdown ( desc, sens ) int desc;/* descripteur de socket */ int sens;/* 0, 1 ou 2 */ 0 indique que le processus ne veut plus recevoir, 1 quil ne veut plus émettre et 2 ni recevoir, ni émettre si un processus tente décrire sur un socket qui a été fermé en reception sur le site distant, il reçoit le signal SIGPIPE

37 37 Signaux SIGIO/SIGURG Le signal SIGIO peut être envoyé par le système à un ou plusieurs processus lorsquun message a été reçu sur un socket : - définir un handler du signal SIGIO (ie. fonction de traitement du signal) - demander lenvoi du signal SIGIO à larrivée dun caractère (fcntl(), FASYNC) - attribuer un groupe propriétaire au socket (fcntl(sock), F_SETOWN, getpid()) De même le signal SIGURG peut être envoyé à un groupe de processus lors de la réception dun caractère urgent (utiliser recv et loption MSG_OOB); celui-ci est repéré dans le flot de données par une marque

38 38 Paramétrage des sockets (1) La primitive getsockopt fournit des informations sur le paramétrage int getsockopt ( desc, niveau, option, o_arg, lg) int desc;/* descripteur de la socket */ int niveau;/* niveau de loption */ int option;/* option à appliquer */ char *p_arg;/* pointeur pour récupérer la valeur */ int *lg;/* à lappel : lg réservée, au retour lg du résultat */ => Quand les options sont définies au niveau de linterface des sockets, la valeur du paramètre option est SOL_SOCKET (pour que la prise en compte des options ait lieu a un autre niveau, utiliser getprotobyname())

39 39 Paramétrage des sockets (2) Modification de la valeur dune option : int setsockopt (desc, niveau, option, p_arg,lg) int desc;/* descripteur du socket */ int niveau;/* niveau de loption */ int option;/* option à appliquer */ char *p_arg;/* pointeur sur largument de loption */ int lg;/* longueur de largument */

40 40 Paramétrage des sockets (3) Valeurs possibles de certaines options SO_TYPEtype de la socket (getsockopt seulement) SO_BROADCASTsi *p_adr=1 diffusion (SOCK_DGRAM seulement) SO_SNDBUF*p_adr = taille du buffer démission SO_RCVBUF*p_adr = taille du buffer de réception

41 41 Source « La communication sous UNIX » Jean-Marie RIFFLET, édition Mc Graw Hill


Télécharger ppt "1 Les sockets UNIX Sylvie Dupuy année 2000."

Présentations similaires


Annonces Google