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

Jean-Christophe Lapayre 1 Unix pour l'utilisateur Les commandes fondamentales.

Présentations similaires


Présentation au sujet: "Jean-Christophe Lapayre 1 Unix pour l'utilisateur Les commandes fondamentales."— Transcription de la présentation:

1 Jean-Christophe Lapayre 1 Unix pour l'utilisateur Les commandes fondamentales

2 Jean-Christophe Lapayre 2

3 3 Vérifier la connexion PC/Unix ping : commande permettant de vérifier qu'une machine est accessible sur le réseau ping adresse_ip ping nom_de machine (nécessite un DNS ou un fichier hosts) Ouverture d'une session interactive La commande telnet rlogin

4 Jean-Christophe Lapayre 4 arborescence / : Répertoire racine, tous les autres répertoires en dépendent. /bin : Contient les binaires fondamentaux à la gestion de Linux. /dev : Contient une multitudes de fichiers dits spéciaux. L'un deux correspond à mon modem. Je dois indiquer ce fichier dans la configuration de mes outils de communication. De même /dev/hda1 correspond à la première partition de mon disque dur IDE, si mon disque dur est un SCSI, son nom sera /dev/sda1. Un dernier exemple : /dev/fd0 correspond à mon lecteur de disquettes. /etc : Contient tous les fichiers de configuration de linux. On y retrouve par exemple le fichier /etc/passwd, qui définit les mots de passe des utilisateurs. /sbin : Contient les binaires du système. On y trouve par exemple la commande shutdown qui permet d'arrêter l'ordinateur. /home : Répertoire qui contient les répertoires des utilisateurs du système. Le répertoire des utilisateurs est automatiquement créé avec la création d'un compte. Tous mes fichiers personnels sont dans /home/(maltesse).

5 Jean-Christophe Lapayre 5 Arborescence suite /lost+found : Répertoire des fichiers perdus. Ces fameux fichiers qui, du fait d'erreur disque, se retrouvent sans chemin d'accès. Le binaire fsck, qui est lancé régulièrement au démarrage de linux, se charge de les détecter et de les stocker dans le répertoire /lost+found /tmp : Répertoire accessible par tous les utilisateurs du système, il permet de ne pas encombrer son répertoire personnel par des fichiers que l'on souhaite de toute manière détruire ou modifier. /var/spool : Répertoire des fichiers qui servent de file d'attente. Par exemple, les files d'attente de l'imprimante se trouvent sous ce répertoire. Les données à imprimer, envoyer,... sont stockées dans ces files d'attentes jusqu'à ce qu'elles soient traitées. /usr : Contient tout ce qui concerne les binaires utiles à tous les utilisateurs et quelques commandes d'administration. On y trouve cependant d'autres choses: /usr/bin contient donc les binaires disponibles pour les utilisateurs et les scripts. /usr/X11R6 : Contient tout ce qui concerne Xfree86 (les bibliothèques, les binaires, la documentation). /usr/include : contient tous les "headers" nécessaires à la programmation dans les différents langages. /usr/lib : Contient toutes les bibliothèques nécessaires au fonctionnement des logiciels. (comme par exemple la bibliothèque C ou C++ ou tcl/tk). /usr/local : On y met ce que l'on veut, mais surtout les fichiers d'usage local.

6 Jean-Christophe Lapayre 6 Manipulation des fichiers Lister les fichiers : ls Créer un fichier vide : touch nom_fichier Créer un fichier en saisissant le contenu directement sur la console cat >nom_fichier Voici mon premier fichier

7 Jean-Christophe Lapayre 7 Manipulation des fichiers Copier de fichiers : cp Afficher le contenu d'un fichier : cat Détruire un fichier : rm Créer un répertoire : mkdir Changer de répertoire : cd Copier un fichier d'un répertoire à l'autre Afficher page à page : more Désigner plusieurs fichiers dans la même commande Les caractères joker Eviter les manipulations hasardeuses* : -i Détruire un répertoire

8 Jean-Christophe Lapayre 8 Créer des alias de commande Pour émuler des commandes déjà connues alias copy=cp Pour positionner des options par défaut alias rm='rm -i' Supprimer un alias défini unalias rm Désactivation temporaire \rm nom_fichier

9 Jean-Christophe Lapayre 9 Détails sur les commandes man : l'indispensable manuel en ligne Unix Ou commande –h Ou commande –help Ou commande --help

10 Jean-Christophe Lapayre 10 bastide]$ man man NAME man - format and display the on-line manual pages manpath - determine user's search path for man pages SYNOPSIS man [-adfhkKtwW] [-m system] [-p string] [-C config_file] [-M path] [-P pager] [-S section_list] [section] name... Le synopsis montre : - Des options facultatives sans paramètres complémentaires : [-adfhkKtwW] - Des options facultatives qui nécessitent un paramètre complémentaire : [-P pager] - Des paramètres optionnels : [section] - Un paramètre obligatoire : name - Le fait que le paramètre obligatoire peut être répété une ou plusieurs fois : name... Décryptage d'une page man

11 Jean-Christophe Lapayre 11 Comparaison commandes : Unix et MS-Dos

12 Jean-Christophe Lapayre 12 Retour sur les commandes Options avancées de cp copie récursive (-r) Options avancées de ls listing long (-l) listing des fichiers cachés (-a) listing récursif (-R) listing avec caractère distinctif (-F) sans inspections des répertoires (-d) Options avancées de rm Destruction récursive (-r) Destruction forcée (-f)

13 Jean-Christophe Lapayre 13 Redirections des Entrées / Sorties

14 Jean-Christophe Lapayre 14 Redirection des Entrées/Sorties Chacune de E/S d'un programme peut être redirigée séparément vers un fichier lire les données d'entrée dans un fichier Envoyer les résultats ou les erreurs dans un fichier

15 Jean-Christophe Lapayre 15 Caractères de redirection Redirection de l'entrée standard wc <.cshrc Redirection de la sortie standard ls > liste

16 Jean-Christophe Lapayre 16 Tubes et filtres La sortie standard d'un programme peut être connectée à l'entrée standard d'un autre Les résultats du premier programme servent de données au deuxième programme Tube (pipe) : suite de commandes réliées par le caractère '|' ls /etc | more Ls –la | grep lapayre

17 Jean-Christophe Lapayre 17 Gestion des fichiers

18 Jean-Christophe Lapayre 18 Différents types de fichiers Unix connaît plusieurs types de fichiers. Ces différents types sont visibles par l'option -l de la commande ls Fichier ordinaire(-) Contient n'importe quel type de données. Dans certains cas, la commande file permet de connaître les données contenues dans ce fichier. Répertoire(d) Contient d'autres fichiers et sous-répertoires. Lien symbolique(l) Permet de désigner le même fichier par plusieurs noms différents Fichier spécial : périphérique en mode caractère (c) Dans le répertoire /dev Fichier spécial : périphérique en mode bloc (b) Tube nommé (named pipe) (p) Utilisation avancée, pour la communication entre processus Socket(s) Idem.

19 Jean-Christophe Lapayre 19 Trois catégories d'utilisateurs Pour chaque fichier, il existe trois type d'utilisateurs : Le propriétaire (owner) du fichier. La personne qui crée un fichier en est propriétaire, jusqu'à ce qu'elle (ou l'administrateur système) utilise la commande chown. Les membres du groupe du propriétaire du fichier. Les autres utilisateurs du système

20 Jean-Christophe Lapayre 20 Trois types d'autorisation Autorisation d'écriture : permet de modifier un fichier, ou de le supprimer. Pour un répertoire, permet de créer des fichiers dans un répertoire ou de les détruire, et de détruire le répertoire lui-même. Autorisation de lecture : permet d'afficher le contenu d'un fichier et de le copier. Pour un répertoire, permet de lister les fichiers contenus dans ce répertoire. Autorisation d'exécution : permet d'exécuter un fichier (il doit s'agir d'un programme compilé ou d'un script). Pour un répertoire, permet de se positionner (cd) dans ce répertoire ou de le traverser (par cd ou ls).

21 Jean-Christophe Lapayre 21 Affichage des autorisations Affichage en mode symbolique Désignation en mode octal

22 Jean-Christophe Lapayre 22 La commande chmod chmod [-Rcfv] mode file... Mode symboliques u,g,o,a : user, group, others, all +,-,= : ajoute, supprime ou fixe le droit r,w,x : read, write, execute Mode octal Chmod – R 777 ~lapayre/tpUnix donne les droits lecture, écriture exécution pour tous sur le répertoire tpUnix (et ses sous-répertoires)

23 Jean-Christophe Lapayre 23 Gestion des processus

24 Jean-Christophe Lapayre 24 Commandes de gestion des processus Lancement d'un processus en tâche de fond nomProcessus & Si oubli : processus déjà lancé, Ctrl Z puis bg Affichage des processus en cours : ps -ef Tuer un processus : kill -9 background

25 Jean-Christophe Lapayre 25 La commande find : tests Par nom: find. -name "*html" -print Par possesseur: find. -user igsi -print Par groupe: find. -group igsi -print Par type: find. -type d -name "*html" –print Par date daccès find. –amin –3 –print Par permissions find. –perm 777 -print Affichage du nom des fichiers trouvés: -print Exécution d'une commande sur les fichiers trouvés: -exec commande {} \; find. -name "*.bak" -exec rm {} \; find. -name "*.bak" -ok rm {} \; Rechercher des fichiers, exécuter des commandes sur les fichiers

26 Jean-Christophe Lapayre 26 Un peu de C # include main () { printf("hello world \n"); } Compilation avec gcc gcc –o hello hello.c gcc rend le fichier hello exécutable

27 Jean-Christophe Lapayre 27 Éditeur Kate kate & cc –o forki.c forki source ex é cutable

28 Jean-Christophe Lapayre 28 un peu de C # include est interpreté par le préprocesseur C. stdio.h est un fichier définissant certaines macro-instructions et certaines variables utilisées par la bibliothèque des E/S. Par convention tous les programmes C possèdent une fonction appelée main. C'est cette fonction qui sera lancée à l'exécution du programme. Les parenthèses vides () indiquent que main n'utilise pas de paramètre. Le texte de main est compris entre 2 accolades { et } ; elles délimitent la fonction( begin end du Pascal ). \n correspond au caractère new-line et provoque le passage à la ligne

29 Jean-Christophe Lapayre la sortie avec format : printf printf ( " libellé + format ",arg1,arg2,...) chaque format est introduit par %, les différents formats sont : d:decimal o:octal x:hexadecimal u:decimal non signé c: un seul caractère s:une chaîne de caractères e:de la forme - m.nnnnnn E xx type float ou double f:de la forme - mmm.nnnnnntype float ou double g:n'impr. pas les zéros non signifi.type float ou double un peu de C 1. Les types de données char caractère intentier floatréel simple précision doubleréel double précision 2. Les entrées-sorties 21. l'entrée et la sortie standard : getchar et putchar getchar() : permet de lire un caractère à la fois depuis le terminal. La fin de fichier ( ^D ou Del sur le terminal ) putchar(x): envoie le caractère x sur le terminal. On peut changer la destination standard en utilisant la réorientation de UNIX.

30 Jean-Christophe Lapayre 30 un peu de C 23. l'entrée avec format : scanf scanf ( " libellé + format ", arg1, arg2,.....) format en entrée : d:entier décimal o:entier en octal x:entier en hexa h:entier de type short c:un seul caractère s: une chaine de caractères f:un nombre en virgule flottante exemple :float a; int b; char baratin [ 10 ] ; scanf ("%f %d %s",&a,&b,baratin );

31 Jean-Christophe Lapayre 31 Construire la commande WC en langage c La commande wc existe (testez la) Il s'agit de la reprogrammer, vous appellerez cette commande wclin Vous utiliserez notamment : getchar() : permet de lire un caractère à la fois depuis le terminal If avec expression dans laquelle &&(et), ||(ou) nb++ (permet dincrémenter un entier nb) '\n' est le caractère de fin de ligne -1 (en fait EOF) correspond à la fin de fichier printf pour afficher les résultats

32 Jean-Christophe Lapayre 32 Construire la commande WC en langage c #include main() { int nbl=0; int nbm=0; int nbc=0; int caract; int oldcaract; while ((caract=getchar())!=-1) { nbc++; if (caract=='\n') nbl++; if (nbc!=1 && ((caract=='\n' && (oldcaract!='\n' && oldcaract!=' ')) || (caract==' ' && (oldcaract!='\n' && oldcaract!=' ')))) nbm++; oldcaract=caract; } if (oldcaract==-1) --nbm; printf("nb lignes : %d, nb mots : %d, nb caract : %d\n",nbl,nbm,nbc); }

33 Jean-Christophe Lapayre 33 Utiliser la commande WC en langage c Créez un fichier de quelques lignes. Appliquez wclin à ce fichier sans modifier le fichier, en utilisant les fonctionnalités de UNIX Redirections ??? Wclin < fichieressai

34 Jean-Christophe Lapayre 34 Construisez la commande WC en langage c avec utilisation darguments Un programme c commence toujours par lappel de la fonction main. Il est possible de passer des paramètres : Main(argc,argv) int argc; char *argv[]; argc est le nombre déléments du tableau argv argv est un pointeur sur le tableau de chaînes de caractères des arguments utilisés par main Par exemple : Lappel « wclin1 fichieressai » de la commande wclin1 donne à argc la valeur 2, argv[0] contient le nom wclin1 et argv[1] contient le nom du fichier fichieressai.

35 Jean-Christophe Lapayre 35 Construisez la commande WC en langage c avec utilisation darguments Construisez wclin1 (wclin adaptée pour utiliser les arg?? En lisant dans un fichier) Vous utiliserez : FILE *fichier;type fichier=fopen(argv[1],"r"); ouverture feof(fichier))fin de fichier caract = fgetc(fichier)lecture caractère/caractère fclose(fichier);fermeture Vous utiliserez cette commande sur un fichier quelconque « wclin1 fichieressai »

36 Jean-Christophe Lapayre 36 #include main(argc,argv) char **argv; int argc; { int nbl=0; int nbm=0; int nbc=0; int caract; int oldcaract; FILE *fichier; /* ouverture du fichier */ printf("%s \n",argv[1]); fichier=fopen(argv[1],"r"); while (!feof(fichier)) { caract=fgetc(fichier); nbc++; if (caract=='\n') nbl++; if (nbc!=1 && ((caract=='\n' && (oldcaract!='\n' && oldcaract!=' ')) || (caract==' ' && (oldcaract!='\n' && oldcaract!=' ')))) nbm++; oldcaract=caract; } fclose(fichier); if (oldcaract==-1) --nbc; printf("nb lignes : %d, nb mots : %d, nb caract : %d\n",nbl,nbm,nbc); } Construisez la commande WC en langage c avec utilisation darguments

37 Jean-Christophe Lapayre 37 Time sharing Lorsque plusieurs processus sont lancés sur un seul processeur, ils se partagent la ressource. Pour visualiser ce phénomène, réalisez un programme c très simple. Il sagit de réaliser une boucle de 20 itérations (avec un for) dans laquelle on place une pause de 5 secondes (sleep(5)) et qui affiche un message identifiant le processus avant la pause et un après. Ce programme sappellera lance, il utilisera la notion darguments de commande : Vous utiliserez « lance proc1 » pour voir les messages de proc1. Vous lancerez en parallèle un processus proc1 et un proc2 pour voir comment le time-sharing opère.

38 Jean-Christophe Lapayre 38 Time sharing #include main(argc,argv) char **argv; int argc; { int i; for (i=0;i<20;i++) { printf("avant sleep %d de %s\n",i+1,argv[1]); sleep(5); printf("après sleep %d de %s\n",i+1,argv[1]); } printf("fin de %s\n",argv[1]); }

39 Jean-Christophe Lapayre 39 Communication entre deux processus liés Un processus peut créer un fils (une duplication complète de lui-même,avec son segment de pile…) par exemple dans une application multimédia, chacun des fils gère un média différent. L instruction Fork( ) crée un tel fils Les threads sont des processus légers. Ils partagent le segment de pile et une partie du segment de données avec le père. Mais la mise en place est beaucoup moins aisée, nous ne l aborderons pas cette année. P1 P2 P3 Son Vidéo

40 Jean-Christophe Lapayre 40 Primitives de gestion des processus Identification d un processus getpid() : n° du processus getppid() : n° du processus père à noter, le père d un processus est par défaut le shell de lancement. Identification du propriétaire getuid() : n° du propriétaire réel getgid() : n° de groupe réel Mise en sommeil sleep(n) : n secondes

41 Jean-Christophe Lapayre 41 Primitive fork() Cette primitive permet la création dynamique d un nouveau processus qui est une copie exacte du processus appelant : il s appelle processus fils. Il hérite de son père : le même code une copie de la zone de données la priorité les propriétaires les descripteurs de fichier … Dans le programme, on teste la valeur de retour de la fonction fork() pour n exécuter que le code correspondant au père ou au fils. valeur 0 on est dans le fils valeur -1 il y a une erreur de création valeur = n 0 on est dans le père, n est le numéro du fils

42 Jean-Christophe Lapayre 42 Exemple de Fork() #include main() { int numfils; int status; numfils = fork(); if (numfils == -1) { printf("erreur de cration \n"); exit(1); } if (numfils == 0) { … /* écrire ici le code du programme fils */ … exit(numfils); /* permet de renvoyer le num du fils */ } else { … /* écrire ici le code du programme père */ … wait(status); /* le père attend le fils pour fermer */ } if (numfils == 0) { … /* écrire ici le code du programme fils */ … exit(numfils); /* permet de renvoyer le num du fils */ } { … /* écrire ici le code du programme père */ … wait(&status); /* le père attend le fils pour fermer */ }

43 Jean-Christophe Lapayre 43 Exemple de Fork() #include main() { int numfils; int *status; numfils = fork(); Switch (numfils) { case –1: printf("erreur de cration \n"); exit(1); break; case 0: … /* écrire ici le code du programme fils */ … exit(numfils); /* permet de renvoyer le num du fils */ break; default: … /* écrire ici le code du programme père */ … wait(&status); /* le père attend le fils pour fermer */ } … /* écrire ici le code du programme fils */ … exit(numfils); /* permet de renvoyer le num du fils */ break; … /* écrire ici le code du programme père */ … wait(&status); /* le père attend le fils pour fermer */ Break;

44 Jean-Christophe Lapayre 44 exit, wait et variable status numfils=fork(); Switch (numfils) { case –1: printf("erreur de création \n"); exit(1); break; case 0: /* écrire ici le code du programme fils */ … exit(numfils); /* permet de renvoyer le num du fils */ /* que VOUS donnez */ break; default: … /* écrire ici le code du programme père */ … wait(&status); /* le père attend le fils pour fermer */ /* affiche le numéro placé dans l'exit*/ printf("le fils %d a quitté \n", (int) status/256); }

45 Jean-Christophe Lapayre 45 Fork itératif for (i=0 ; i < nbfils ; i++) { val=fork(); if (val==0) { /* un fils */ int n,num; char message[15]; printf("je suis le fils %d de ID %d et de pere %d \n", i,getpid(),getppid()); … blabla … exit(i); } for (i=0;i

46 Jean-Christophe Lapayre 46 Communication entre père et fils Entre un processus père et un fils, il est possible de communiquer par : Fichier mémoire partage : shared memory par sockets : AF_INET ou AF_UNIX, TCP ou UDP par tubes les tubes nommés utilisant la primitive open les tubes anonymes utilisant la primitive pipe Les tubes anonymes ne sont utilisables quentre des processus apparentés.

47 Jean-Christophe Lapayre 47 Les tubes Les tubes (pipes) permettent le transfert de données entre des processus selon un schéma premier entré / premier sorti (FIFO) Leur mise en œuvre permet aux processus de communiquer même s ils ne connaissent pas les processus qui sont à l autre bout du tube. Nous ne développerons ici que la mise en place des tubes anonymes.

48 Jean-Christophe Lapayre 48 Communication entre père et fils par tubes anonymes Un tube est unidirectionnel Pour écrire sur un tube, il faut le fermer en lecture Pour lire dans un tube, il faut le fermer en écriture Pour un tube donné, un processus sera ou bien écrivain, ou bien lecteur, mais pas les deux en même temps. C est un mode de fonctionnement totalement asynchrone. Les valeurs sont écrites par un processus, la seule garantie est l ordre FIFO pour la lecture. Ecriture lecture TUBE

49 Jean-Christophe Lapayre 49 Fonctionnement des tubes Si les processus doivent échanger des données, il faut deux tubes un père/fils et un fils/père Processus écrivain Processus lecture

50 Jean-Christophe Lapayre 50 Exemple de tubes #include #define lire 0 #define ecrire 1 main() { int no_fils,n; int *status; char c; /* declaration des tubes */ int tubepf[2],tubefp[2]; printf("DEBUT : Je suis le processus PERE %d \n",getpid()); printf("DEBUT : No du grand-pere %d \n",getppid()); /* initialisation des pipes */ pipe(tubefp); pipe(tubepf); if ((no_fils=fork())==-1) { printf("Je suis le PERE impossible de cree le fils \n"); exit (1); } Tube où le père écrit et le fils lit : du P ère vers le F ils Tube où le fils écrit et le père lit : du F ils vers le P ère

51 Jean-Christophe Lapayre 51 if (no_fils !=0) { char message[15]; int n,num; printf(" PERE le no du fils est %d \n",no_fils); printf(" PERE j attends la fin de mon fils\n"); /* le pere envoie au fils son numero */ num = no_fils; close(tubepf[lire]); /*fermeture en lecture du tube d'ecriture*/ n=write(tubepf[ecrire],&num,sizeof(num)); /* le pere lit "merci" de son fils */ close(tubefp[ecrire]); /*fermeture en ecriture du tube en lecture*/ n=read(tubefp[lire],&message,sizeof(message)); printf(" PERE : j'ai recu %s\n",message); /* le pere envoie "pas de quoi" au fils */ strcpy(message,"pas de quoi"); n=write(tubepf[ecrire],&message,sizeof(message)); /*fermeture final de PF en ecriture et FP en lecture */ close(tubepf[ecrire]); close(tubefp[lire]); wait (&status); printf(" PERE : fin du fils avec status %d %d\n",n,(int)status/256); } Exemple de tubes

52 Jean-Christophe Lapayre 52 else { int no_proc,pere_proc,num; char message[15]; no_proc=getpid();pere_proc=getppid(); printf("FILS : mon num est %d\n",no_proc); printf("FILS : num de mon pere est %d\n",pere_proc); /* le fils recoit du pere son numero qui confirme getpid()*/ close(tubepf[ecrire]); n=read(tubepf[lire],&num,sizeof(num)); printf("FILS : j'ai recu %d qui confirme mon numero\n",num); /* le fils remercie son pere */ close(tubefp[lire]); strcpy(message,"merci"); n=write(tubefp[ecrire],&message,sizeof(message)); /* le fils recoit du pere "pas de quoi" */ n=read(tubepf[lire],&message,sizeof(message)); printf("FILS : j'ai recu %s\n",message); /*fermeture final de FP en ecriture et PF en lecture */ close(tubepf[lire]); close(tubefp[ecrire]); printf("FILS : je termine \n"); exit(1); } Exemple de tubes

53 Jean-Christophe Lapayre 53 Les sockets Application cliente API Socket UDPTCP IP Physique Application : serveur API Socket UDPTCP IP Physique Protocole Applicatif

54 Jean-Christophe Lapayre 54 Sockets : labstraction comme un descripteur de fichier dans le système UNIX, associe un descripteur à un socket; le concepteur dapplication utilise ce descripteur pour référencer la communication client/serveur sous-jacente. une structure de données «socket» est créée à l ouverture de socket; table de descripteur de fichiers Family: Service: Local IP: Remote IP: Local Port: Remote Port: Table de descripteurs de processus Structure Socket La primitive socket permet louverture de cette socket; initialement, après lappel à cette fonction, la structure de données associée au socket est principalement vide, les appels à dautres primitives de linterface socket renseigneront ces champs vides.

55 Jean-Christophe Lapayre 55 Les Sockets : Mode connecté SERVEUR socket bind listen accept close CLIENTMODE CONNECTE En mode connecté il y a établissement (listen,connect, accept) puis libération (close) dune connexion entre le cleint et le serveur. socket connect connexion recv send recv requête réponse

56 Jean-Christophe Lapayre 56 Les Sockets : primitives Elles permettent détablir un lien de communication en mode connecté ou non-connecté sur un réseau, Structurent une application soit en mode client, soit en mode serveur, Permettent déchanger des données entre ces applications. La primitive socket: point dencrage qui permet à lapplication dobtenir un lien de communication vers la suite de protocole qui servira déchange, définit le mode de communication utilisé (connecté ou non- connecté). La primitive bind: permet de spécifier le point de terminaison local (essentiellement le port TCP/UDP dans lenvironnement TCP/IP). la primitive connect: permet à un client détablir une communication active avec un serveur, le point de terminaison distant (adresse IP + port TCP/UDP dans lenvironnement TCP/IP) est spécifié lors de cet appel.

57 Jean-Christophe Lapayre 57 Les Sockets : primitives la primitive listen : permet à un serveur dentrer dans un mode découte de communication, dés lors le serveur est « connectable » par un client, le processus est bloqué jusquà larrivée dune communication entrante. la primitive accept : permet à un serveur de recevoir la communication entrante (client), crée un nouveau socket et retourne le descripteur associé à lapplication. le serveur utilise ce descripteur pour gérer la communication entrante le serveur utilise le descripteur de socket précédent pour traiter la prochaine communication à venir. les primitives send et recv: Lorsque la communication est établie, client et serveur échangent des données afin dobtenir (client) et transmettre (serveur) le service désiré. En mode connecté, clients et serveurs utilisent send et recv; en mode non- connecté, ils utilisent les primitives recvfrom et sendto. la primitive close : termine la connexion et libère le socket associé.

58 Jean-Christophe Lapayre 58 Les Sockets : Mode non connecté SERVEUR socket bind sendto recvfrom sendto recvfrom close socket CLIENT bind

59 Jean-Christophe Lapayre 59 Socket : Mode non connecté En mode non-connecté: le client nétablit pas de connexion avec le serveur mais émet un datagramme (sendto) vers le serveur. Le serveur naccepte pas de connexion, mais attend un datagramme dun client par recvfrom qui transmet le datagramme à lapplication ainsi que ladresse client. Les sockets en mode non-connecté peuvent utiliser la primitive connect pour associer un socket à une destination précise ==> send peut alors être utilisée à la place de la sendto, De même, si ladresse de lémetteur dun datagramme nintéresse pas un processus la primitive recv peut être utilisée à la place de la primitive recvfrom.

60 Jean-Christophe Lapayre 60 Sockets : gestion de noms Les primitives gethostname et sethostname Dans le monde UNIX, la primitive gethostname permet aux processus utilisateurs daccéder au nom de la machine locale. Dautre part, la primitive sethostname permet à des processus privilégiés de définir le nom de la machine locale. La primitive getpeername Cette primitive est utilisée afin de connaître le point de terminaison du distant. Habituellement, un client connaît le point de terminaison (couple port/adresse IP) puisquil se connecte à ce serveur distant; cependant, un serveur qui utilise la primitive accept pour obtenir une connexion, a la possibilité dinterroger le socket afin de déterminer ladresse du distant. La primitive getsockname Cette primitive rend le nom associé au socket qui est spécifié en paramètre.

61 Jean-Christophe Lapayre 61 Sockets : gestion de noms Lorsque ces fonctions sont exécutées sur des machines ayant accès à un serveur de noms de domaines, elles fonctionnent elles-mêmes en mode client/serveur en émettant une requête vers le serveur de nom de domaines et attendent la réponse. Lorsquelles sont utilisées sur des machines qui nont pas accès à un serveur de noms, elles obtiennent les informations à partir dune base de données ( simple fichier) locale. gethostbyname spécifie un nom de domaine et retourne un pointeur vers une structure hostent qui contient les informations propres à ce nom de domaine. gethostbyaddr permet dobtenir les mêmes informations à partir de ladresse spécifiée. getnetbyname spécifie un nom de réseau et retourne une structure netent renseignant les caractéristiques du réseau. getnetbyaddr spécifie une adresse réseau et renseigne la structure netent

62 Jean-Christophe Lapayre 62 Sockets exemple : fichier serveur /* SERVEUR */ #include /* Utilise pour les codes d'erreurs */ extern int errno; main() { int sock_cont,sock_cli,err; struct sockaddr_in nom_control,/* adresse de la sochet de controle */ nom_transmis;/* adresse de la socket de transmission */ int size_addr_cont,/* taille de l'adresse d'une socket */ size_addr_trans; char myHost[20]; /* Pour memoriser mon nom */ struct hostent myHostEnt; /* hostent de ma machine */ struct hostent *hostEnt; struct hostent *gethostent(); size_addr_cont = sizeof(struct sockaddr_in); size_addr_trans = sizeof(struct sockaddr_in);

63 Jean-Christophe Lapayre 63 Sockets exemple : fichier serveur /* Creation de la socket, protocole TCP */ sock_cont = socket(AF_INET, SOCK_STREAM, 0); if (sock_cont < 0) { printf("serveur: erreur de socket\n"); exit(); } /* Initialisation de l'adresse de la socket */ err = gethostname(myHost, sizeof(myHost)); if (err < 0) { printf("Erreur %d dans gethostname", errno); exit(); } else { printf("Sur le host : %s\n", myHost); } hostEnt = gethostbyname(myHost); if ((int) hostEnt < 0) { printf("Erreur %d in gethostbyname", errno); exit(); } nom_control.sin_family = AF_INET; nom_control.sin_port = 0; bcopy(hostEnt->h_addr, &nom_control.sin_addr, hostEnt->h_length); bzero(nom_control.sin_zero, 8);

64 Jean-Christophe Lapayre 64 Sockets exemple : fichier serveur /* Association socket-adresse */ err = bind(sock_cont, &nom_control, size_addr_cont); if (err < 0) { printf("Erreur %d sur le bind\n", errno); exit(); } /* Recupere l'adresse de la socket */ err = getsockname(sock_cont, &nom_control, &size_addr_cont); if (err < 0) { printf("Error %d in getsockname", errno); exit(); } printf("Port number : %d\n", nom_control.sin_port); /* Utilisation en socket de controle */ err = listen(sock_cont,1); if (err < 0) { printf("Erreur %d sur listen\n", errno); exit(); } /* Attente et acceptation de la demande de connexion */ sock_cli = accept(sock_cont, &nom_transmis, &size_addr_trans); if (sock_cli < 0) { printf("Erreur %d sur accept\n", errno); perror("accept"); exit(); } i=0; printf("client connecte\n")

65 Jean-Christophe Lapayre 65 Sockets exemple : fichier serveur /* envoi du numero au client : pour la numerotation */ send(sock_cli,&i,sizeof(i),0); printf("Num client envoye\n"); /* attente des accuses-reception */ recv(sock_cli,&num,sizeof(num),0); if (err < 0) { printf("Erreur %d dans la reception\n", errno); exit(); } printf("j'ai recu l'accuses \n"); /* envoi du message de fin=-1 */ num=-1; send(sock_cli,&num,sizeof(num),0); if (err < 0) { printf("Erreur %d dans l'envoi\n", errno); exit(); } printf("fin envoye\n"); printf("j'attends les fermetures\n"); /* attente pour que les clients ferment avant */ recv(sock_cli,&num,sizeof(num),0); if (err < 0) { printf("Erreur %d dans la reception\n", errno); exit(); } /*on peut fermer le serveur */ printf("OK tout est recu\n"); sleep(3); printf("Fin\n"); /* arret de la connexion */ shutdown(sock_cli, 2); /* Fermeture de la socket client */ close(sock_cont); /* fermeture de la socket de controle */ }

66 Jean-Christophe Lapayre 66 Sockets exemple : fichier client /* CLIENT */ #include #define OK 1 #define QUIT -1 /* Utilise pour les codes d'erreurs */ extern int errno; /* Chaine envoyee au serveur-recepteur */ #define chaine "Hello world !" main(argc,argv) char **argv; int argc; { int sock,/* descipteur de la socket locale */ err,num;/* code d'erreur */ struct sockaddr_in nom;/* adresse de la sochet */ int size_addr_in = sizeof(struct sockaddr_in); int port;

67 Jean-Christophe Lapayre 67 Sockets exemple : fichier client char remHost[20], /* nom de la machine distante */ reponse[2]; /* test d'envoi de message */ struct hostent remHostEnt; struct hostent *hostEnt; struct hostent *gethostbyname(); /* Creation de la socket, protocole TCP */ sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { printf("Erreur %d a la creation de socket\n", errno); exit(); } /* Initialisation de l'adresse de la socket */ nom.sin_family = AF_INET; /* Recherche de l'adresse de la machine */ hostEnt = gethostbyname(argv[1]); if ((int) hostEnt < 0) { printf("Error %d in gethostbyname", errno); exit(); } bcopy(hostEnt->h_addr, &nom.sin_addr, hostEnt->h_length);

68 Jean-Christophe Lapayre 68 Sockets exemple : fichier client /* Recherche du numero de port du serveur */ nom.sin_port = atoi(argv[2]); bzero(nom.sin_zero, 8); /* Connection au serveur */ err = connect(sock, &nom, size_addr_in); if (err < 0) { printf("Erreur %d a la connection de socket\n", errno); exit(); } /* Reception et affichage du numero du client */ err = recv( sock, &num, sizeof(num),0); if (err < 0) { printf("Erreur %d dans la reception\n", errno); exit(); } printf("je suis le %d connecte\n",num); /* envoi de l'accuse-reception */ num = OK; err = send( sock, &num, sizeof(num), 0); if (err < 0) { printf("Erreur %d dans l'envoi\n", errno); exit(); }

69 Jean-Christophe Lapayre 69 printf("ack envoye\n"); /* reception du -1 de QUIT */ err = recv( sock, &num, sizeof(num),0); if (err < 0) { printf("Erreur %d dans la reception\n", errno); exit(); } printf("quit recu\n"); /* envoi de la confirmation de quit */ num = QUIT; err = send( sock, &num, sizeof(num), 0); if (err < 0) { printf("Erreur %d dans l'envoi\n", errno); exit(); } printf("quit confirme\n"); printf("Fin\n"); /* Fermeture de la connexion */ shutdown( sock, 2); /* Fermeture de la socket */ close(sock); } Sockets exemple : fichier client

70 Jean-Christophe Lapayre 70 Serveur itératif Dans un système avec un serveur et n clients, plusieurs solutions sont possibles : Le nombre de clients est fixe Le système peut fonctionner dès le premier client L'attente des clients dans la première solution est bloquante, dans le deuxième cas l'attente est dite passive.

71 Jean-Christophe Lapayre 71 Mode connecté : multiclient SERVEUR Sockcont=socket(… bind Listen(sockcont,4) Num=0 Cli[Num]=accept(… send Num++ socket connect recv Recv de son propre num socket connect recv Recv de son propre num socket connect recv Recv de son propre num socket connect recv

72 Jean-Christophe Lapayre 72 L'attente passive : select Dans l'exemple précédent il faut attendre les quatre connections pour quitter la boucle. La fonction select(…) permet l'attente passive sur différents "descripteurs" : écriture clavier, demande de connexion, réception de message. Les listes de descripteurs sont de type fd_set comme par exemple fd_set lire, ecrire; FD_ZERO mise à zéro d'une liste de descripteurs FD_ZERO(&lire); FD_ZERO(&ecrire); FD_SET définition d'une liste de descripteurs FD_SET(0,&lire); /* attente clavier */ FD_SET(sock_cont,&lire); /* attente sur */ FD_SET(sock_cont,&ecrire); /*sock_cont pour connexion*/ for (i=0;i

73 Jean-Christophe Lapayre 73 Mise en attente passive : n = select(32, &lire, &ecrire, NULL, NULL); Déclenchement des descripteurs if (FD_ISSET(0,&lire)) {… /* déclenchement clavier */ /* connection d'un nouveau */ if ((FD_ISSET(sock_cont,&lire)) || (FD_ISSET(sock_cont,&ecrire))) { sock_cli[nbcli]=accept(sock_cont,&nom_transmis,&taille); err = send( sock_cli[nbcli],&nbcli, sizeof(nbcli), 0); nbcli ++; } /* demandes de connection */ for (i=0;i

74 Jean-Christophe Lapayre 74 L'attente passive : select … err = listen(sock_cont, 5); if (err < 0) { printf("serveur: Erreur %d sur listen\n", errno); exit(); } nbcli=0; /* debut du select */ for (;;) { FD_ZERO(&lire); FD_ZERO(&ecrire); FD_SET(0,&lire); FD_SET(sock_cont,&lire); FD_SET(sock_cont,&ecrire); for (i=0;i

75 Jean-Christophe Lapayre 75 L'attente passive : select for (i=0;i


Télécharger ppt "Jean-Christophe Lapayre 1 Unix pour l'utilisateur Les commandes fondamentales."

Présentations similaires


Annonces Google