UE NSY 103 Programmation Système. EXAMEN 2007-2008 Session Septembre. documents autorisés : Non. Session 2008 NSY 103 (S. Cherrier) Page 1 / 9



Documents pareils
Cours Programmation Système

Programmation système de commandes en C

Cours 6 : Tubes anonymes et nommés

GESTION DES FICHIERS C/UNIX

Applications client/serveur TCP/IP - Sockets Rappels. C.Crochepeyre Applications CS 1

3IS - Système d'exploitation linux - Programmation système

TRAVAUX PRATIQUES Programmation Système Langage C / Système UNIX. 2 e année Génie Informatique

Programmation système en C/C++

Le système de gestion des fichiers, les entrées/sorties.

Les processus. Système L3, /39

Communication par sockets

Communication sous UNIX les sockets

Le prototype de la fonction main()

Cours de Système : Gestion de Fichiers

Introduction aux Systèmes et aux Réseaux

Cours admin 200x serveur : DNS et Netbios

Travaux Pratiques Introduction aux réseaux IP

Programmation système I Les entrées/sorties

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Compression de Données - Algorithme de Huffman Document de Conception

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Serveurs de noms Protocoles HTTP et FTP

Exercice sur les Dockers

Dans le chapitre 1, nous associions aux fichiers ouverts des descripteurs de fichiers par lesquels nous accédions aux fichiers.

Programmation C. Apprendre à développer des programmes simples dans le langage C

L annuaire et le Service DNS

Plan global. Programmation système II. Socket du domaine UNIX. Plan. Socket UNIX, Terminaux, Async IO, Mémoire, ELF.

Processus! programme. DIMA, Systèmes Centralisés (Ph. Mauran) " Processus = suite d'actions = suite d'états obtenus = trace

1. Fonctionnement de l Internet 2. Protocoles applicatifs 3. Programmation réseau

Présentation du modèle OSI(Open Systems Interconnection)

SYSTÈME DE GESTION DE FICHIERS

Le service FTP. M.BOUABID, Page 1 sur 5

Programmation Réseau. ! UFR Informatique ! Jean-Baptiste.Yunes@univ-paris-diderot.fr

Programmation Internet en Java

Programmation impérative

Qu'est-ce qu'un processus: Définitions

Cahier des charges. driver WIFI pour chipset Ralink RT2571W. sur hardware ARM7

Simulation d un système de paiement par carte bancaire

Les structures de données. Rajae El Ouazzani

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

OS Réseaux et Programmation Système - C5

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

II/ Le modèle OSI II.1/ Présentation du modèle OSI(Open Systems Interconnection)

Master d'informatique 1ère année. Réseaux et protocoles. Architecture : les bases

Playing with ptrace() for fun and profit

I. Introduction aux fonctions : les fonctions standards

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Protocoles réseaux. Abréviation de Binary Digit. C'est la plus petite unité d'information (0, 1).

le minimum pour communiquer par réseau (sans toutefois y comprendre grand chose)

Cours de C. Allocation dynamique. Sébastien Paumier

Archivage Messagerie Evolution pour usage HTML en utilisant Hypermail

LA mémoire principale est le lieu où se trouvent les programmes et les

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Chapitre V : La gestion de la mémoire. Hiérarchie de mémoires Objectifs Méthodes d'allocation Simulation de mémoire virtuelle Le mapping

TP a Notions de base sur le découpage en sous-réseaux

Le protocole TCP. Services de TCP

SYSTÈME DE GESTION DE FICHIERS SGF - DISQUE

Introduction à la Programmation Parallèle: MPI

LEs processus coopèrent souvent pour traiter un même problème. Ces

Le Network File System de Sun (NFS)

TR2 : Technologies de l'internet. Chapitre VII. Serveur DHCP Bootp Protocole, Bail Relais DHCP

DNS Server RPC Interface buffer overflow. Céline COLLUMEAU Nicolas BODIN

6 - Le système de gestion de fichiers F. Boyer, UJF-Laboratoire Lig, Fabienne.Boyer@imag.fr

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Gestion de la mémoire

Conventions d écriture et outils de mise au point

Sur un ordinateur exécutant Windows 2000 Server Ayant une adresse IP statique

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

Réseau : Interconnexion de réseaux, routage et application de règles de filtrage.

LA COUCHE TRANSPORT CONTRÔLE LE FLOT DE DONNEES TRANSMISES par la couche Réseau

Les structures. Chapitre 3

Architecture des ordinateurs

Réseaux IUP2 / 2005 DNS Système de Noms de Domaine

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Cours 14 Les fichiers

DUT Informatique Module Système S4 C Département Informatique 2009 / Travaux Pratiques n o 5 : Sockets Stream

Introduction au langage C

Introduction. Adresses

Le langage C. Séance n 4

NOTIONS DE RESEAUX INFORMATIQUES

NOTE D'APPLICATION CONCERNANT LA MISE EN SERVICE DE MATERIELS SUR RESEAU IP

Programmation Réseau. Anthony Busson IUT Info Lyon 1

Bases de programmation. Cours 5. Structurer les données

Lier Erlang avec d autres langages de programmation

Programmation Système (en C sous linux) Rémy Malgouyres LIMOS UMR 6158, IUT département info Université Clermont 1, B.P.

Couche application. La couche application est la plus élevée du modèle de référence.

Java Licence Professionnelle CISII,

Firewall. Souvent les routeurs incluent une fonction firewall qui permet une première sécurité pour le réseau.

Chapitre 1 : La gestion dynamique de la mémoire

Stockage du fichier dans une table mysql:

Dossier de réalisation d'un serveur DHCP et d'un Agent-Relais SOMMAIRE. I. Principe de fonctionnement du DHCP et d'un Agent-Relais

Institut Supérieure Aux Etudes Technologiques De Nabeul. Département Informatique

Chapitre : Les Protocoles

Concept de machine virtuelle

Développement d un logiciel de messagerie instantanée avec Dotnet (version simplifiée)

Classe ClInfoCGI. Fonctions membres principales. Gestion des erreurs

Protocoles IP (2/2) M. Berthet. Les illustrations sont tirées de l ouvrage de Guy Pujolle, Cours réseaux et Télécom Contributions : S Lohier

TP2 - Conguration réseau et commandes utiles. 1 Généralités. 2 Conguration de la machine. 2.1 Commande hostname

Gestion des processus

Transcription:

UE NSY 103 Programmation Système EXAMEN 2007-2008 Session Septembre documents autorisés : Non Session 2008 NSY 103 (S. Cherrier) Page 1 / 9

Une sonde WEB L'équipe de développement dans laquelle vous travaillez est chargée de la réalisation d'une petite sonde autonome de surveillance. Cette sonde teste la disponibilité de l'accès aux serveurs, et peut soit émettre une alerte en direction des services centraux, soit répondre à des interrogations du système central. Il s'agit d'un petit boitier qui sera installé sur un site distant, et connecté au réseau local. Ce produit répond à un besoin des services informatiques centraux, quand ceux-ci offrent des solutions complètes d'accès pour des utilisateurs dans des locaux distants (cas de franchises, concessionnaires, succursales, etc : Des établissements très éloignés qui ont besoin d'échanger de l'information avec le système de la maison mère, que ce soit pour l'accès au stock, la remontée d'informations dans le cadre du suivi de la clientèle, de suivi de produit etc). Très souvent, dans le cas d'établissements de petite taille, les problèmes d'accès (que ce soit un problème de réseau, ou du service) ne sont détectés que lorsque l'utilisateur se rend compte qu'il est «planté». La panne n'est donc traitée que lorsqu'il est trop tard, à posteriori. La sonde, placée au plus près de l'utilisateur, va simuler très régulièrement une utilisation standard des ressources offertes (interrogation, réservation puis annulation, etc). En cas de panne du réseau ou de problème d'accès au service, quel qu'il soit, la sonde permettra aux informaticiens du site central une réaction bien plus rapide, avant même que l'utilisateur distant ne se rende compte de l'interruption (Même en cas de rupture du réseau, on est alerté : si on sait que la sonde d'une succursale, prenons Nevers par exemple, doit simuler une interrogation de notre stock toutes les 10 minutes, l'absence de connexion provenant de Nevers sur le serveur de stock durant le dernier quart d'heure sera là encore une indication de rupture de connexion avec ce site). Le site central pourra interroger régulièrement lui aussi chacune des sondes afin d'obtenir des statistiques sur les pannes et leurs durées, sur les temps de réponse du service, et d'autres statistiques. Elle est donc configurable afin de lui faire réaliser des tests, et offre aussi un accès aux statistiques. Question 1 : Connexion réseau (8 pts) -1.a) Sockets [2 points] Comment est caractérisé un socket réseau? -1.b) Gestion de fichiers et sockets[2 points] Décrire les primitives de base utilisées pour travailler avec les fichiers. Même chose avec les sockets. Session 2008 NSY 103 (S. Cherrier) Page 2 / 9

-1.c) Explication du code [2 point] Expliquer ce que fait le code aux endroits indiqués (ANNEXE 1) -1.d) Écriture du code manquant [2 points] Compléter le code (ANNEXE1) afin d'envoyer la requête (REQUEST) au serveur et de rendre compte dans le fichier de log (OK_RESPONSE ou ERROR_MESSAGE) Question 2 : Matériel (4 pts) -2.a) Choix de matériel [1 points] La plate forme matérielle utilisée pour la sonde utilise un CPU little-endian («petit-boutiste»). Expliquez cette notion. Quel peut être l'impact de cette caractéristique? -2.b) Explication [3 points] Décrire et comparer la gestion de la mémoire par segmentation et par pagination. Question 3 : Processus (8 pts) Votre sonde tourne sous un système d'exploitation Linux. Ce système est multiprocessus. -3.a) processus [2 points] A quoi correspond un processus? Comment l'identifier précisement? Que contient-il? Et comment sont organisés les processus dans un système d'exploitation? -3.b) Primitives [2 points] Quel est le cycle de vie d'un processus? Quelles sont les primitives systèmes qui permettent de gérer les processus? -3.c) Écriture d'un programme multi-tâche[4 points] Écrivez un programme qui récupère les programmes dont les noms sont passés en arguments sur la ligne de commande, puis les exécute dans des processus fils. Session 2008 NSY 103 (S. Cherrier) Page 3 / 9

#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <unistd.h> #include <string.h> #include <fcntl.h> Annexe 1 : Code du programme Test #define SERVER_PORT 80 /* port ou se connecter */ #define BUFFER_SIZE 15 /* taille du buffer pour la reponse */ #define OK_MESSAGE "Connexion active" /* message quand tout est okay */ #define ERROR_MESSAGE "Pas de connexion" /* message d'erreur */ #define REQUEST "GET / HTTP/1.0\nHost: pc\n\n" /* la requête HTTP */ #define OK_RESPONSE "HTTP/1.0 200 OK" /* la réponse HTTP */ int main(int argc,char* argv[]) { int soc; /* no de socket */ struct sockaddr_in sock_in; /* infos de connexion */ struct hostent * host; /* adresse IP du serveur */ int ncarlu; /* nombre d'octets lus */ char buffer[buffer_size]; /* buffer */ int fd; /* fichier en ecriture */ /* Creation de la socket (pas de connexion encore) */ soc = socket(af_inet, SOCK_STREAM, 0); if ( soc == -1 ) { COMMENTEZ ICI perror("socket"); /* Remplissage de la structure permettant d'indiquer ou se connecter */ bzero(&sock_in, sizeof(sock_in)); /* mise a zero de la structure */ sock_in.sin_family = AF_INET; /* Type de connexion */ sock_in.sin_port = htons(server_port); /* COMMENTEZ ICI*/ /* On recupere COMMENTEZ ICI */ host = gethostbyname(argv[1]); if ( host == NULL ) { /* ici, on ne peut PAS utiliser perror car la variable contenant */ /* l'erreur n'est PAS errno. Donc il faut gerer les erreurs nous-meme. */ switch(h_errno) { case HOST_NOT_FOUND: fprintf(stderr, "gethostbyname : Hote inconnu.\n"); case NO_ADDRESS: fprintf(stderr, "gethostbyname : Pas d'adresse IP associee a ce nom.\n"); case NO_RECOVERY: fprintf(stderr, "gethostbyname : Erreur fatale du serveur de noms.\n"); case TRY_AGAIN: fprintf(stderr, "gethostbyname : Erreur temporaire du serveur de noms.\n"); /* switch */ /* On recopie l'adresse IP du serveur dans la structure */ bcopy(host->h_addr, &sock_in.sin_addr.s_addr, host->h_length); /* Connexion */ if ( connect(soc, (struct sockaddr *)(&sock_in), sizeof(sock_in)) == -1 ) { perror("connect"); /* ouverture du fichier de log*/ Session 2008 NSY 103 (S. Cherrier) Page 4 / 9

fd=open("/var/log/message",o_wronly O_TRUNC O_CREAT,"0660"); if (fd==-1) { perror("erreur création fichier"); /* on déclenche la lecture de la page web */ ECRIRE LE CODE ICI return 0; Session 2008 NSY 103 (S. Cherrier) Page 5 / 9

1-a) Corrigé Les deux principales options sont le mode connecté (TCP, avec mise en place de connexions fiables), et le mode non connecté (UDP, communication via datagrammes). Un socket est caractérisé par 5 informations : les adresses ip de chaque coté du socket, les ports de chaque coté du socket, et enfin le type de socket (TCP ou UDP). Par exemple, l'ouverture d'une connexion réseau via le système de socket sur le serveur web www.cnam.fr nécessite le socket suivant : adresse ip du serveur du cnam (163.173.128.50), le port du service (80), mon adresse ip (88,254,XX.xxx), un port client (1075), et le type TCP (le protocole HTTP est de type connecté) 1-b) La gestion des fichiers de bas niveau en C système utilise principalement 4 primitives : open(), close(), read() et write() int open(char * pathname, int flags, mode_t mode) le pathname, c'est le nom du fichier (trivial) les flags permettent de décrire le mode d'ouverture (O_RDONLY, O_WRONLY ou O-RDWR). A combiner avec d'autres attributs tels que O_CREAT, O_APPEND ou O_TRUNC). On combine ces attributs avec des OU ( ) Enfin, les modes correspondent aux droits du fichiers. L'int renvoyé est le file descripteur, un entier qui permet de se référer ensuite à ce fichier. int close(int fd) Ferme le fichier; et renvoie 0 ou -1 si erreur. ssize_t read(int fd, void *buffer, size_t taille) ssize_t write(int fd, void *buffer, size_t taille) Un buffer est un espace d'une taille définie arbitrairement qu'on pourra manipuler... On peut par exemple utiliser un tableau de XXX char dans notre cas. Char buffer[1024]; est un excellent candidat pour ce genre de choses. Un tableau de char comme celui-ci est en fait un pointeur sur le début de la zone, donc, l'utilisation est assez simple. Lecture : On indique le nombre de caractère qu'on veut lire (taille). La primitive read() déclenche la lecture et remplit le buffer. Elle renvoie le nombre de caractères lus ou -1 en cas de problème. Le nb de caractères peut être inférieur à la taille demandée, en cas de fin de fichier, ou si on lit des fichiers un peu particuliers. (on gardera bien la valeur de result, si on veut manipuler ensuite le buffer, pour éviter de sortir de l'espace utilisé) Ecriture : idem, on donne le buffer à écrire, et la taille du buffer. 1c et 1d) #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> Session 2008 NSY 103 (S. Cherrier) Page 6 / 9

#include <unistd.h> #include <string.h> #include <fcntl.h> #define SERVER_PORT 80 /* port ou se connecter */ #define BUFFER_SIZE 15 /* taille du buffer pour la reponse */ #define OK_MESSAGE "Connexion active" /* message quand tout est okay */ #define ERROR_MESSAGE "Pas de connexion" /* message d'erreur */ #define REQUEST "GET / HTTP/1.0\nHost: pc\n\n" /* la requête HTTP */ #define OK_RESPONSE "HTTP/1.0 200 OK" /* la réponse HTTP */ int main(int argc,char* argv[]) { int soc; /* no de socket */ struct sockaddr_in sock_in; /* infos de connexion */ struct hostent * host; /* adresse IP du serveur */ int ncarlu; /* nombre d'octets lus */ char buffer[buffer_size]; /* buffer */ int fd; /* fichier en ecriture */ /* Creation de la socket (pas de connexion encore) */ soc = socket(af_inet, SOCK_STREAM, 0); if ( soc == -1 ) { perror("socket"); /* Remplissage de la structure permettant d'indiquer ou se connecter */ bzero(&sock_in, sizeof(sock_in)); /* mise a zero de la structure */ sock_in.sin_family = AF_INET; /* Type de connexion */ sock_in.sin_port = htons(server_port); /* port auquel on veut se connecter */ /* (avec mise des octets dans le bon ordre) */ /* On recupere l'adresse du serveur auquel on veut se connecter */ host = gethostbyname(argv[1]); if ( host == NULL ) { /* ici, on ne peut PAS utiliser perror car la variable contenant */ /* l'erreur n'est PAS errno. Donc il faut gerer les erreurs nous-meme. */ switch(h_errno) { case HOST_NOT_FOUND: fprintf(stderr, "gethostbyname : Hote inconnu.\n"); case NO_ADDRESS: fprintf(stderr, "gethostbyname : Pas d'adresse IP associee a ce nom.\n"); case NO_RECOVERY: fprintf(stderr, "gethostbyname : Erreur fatale du serveur de noms.\n"); case TRY_AGAIN: fprintf(stderr, "gethostbyname : Erreur temporaire du serveur de noms.\n"); /* switch */ /* On recopie l'adresse IP du serveur dans la structure */ bcopy(host->h_addr, &sock_in.sin_addr.s_addr, host->h_length); /* Connexion */ if ( connect(soc, (struct sockaddr *)(&sock_in), sizeof(sock_in)) == -1 ) { perror("connect"); /* ouverture du fichier */ fd=open("/var/log/message",o_wronly O_TRUNC O_CREAT,"0660"); if (fd==-1) { perror("erreur création fichier"); /* on déclenche la lecture de la page web */ write(soc,request,strlen(request)); /* lit et affiche la reponse */ ncarlu = read(soc, buffer, BUFFER_SIZE); printf(buffer); /* affichage pour trace */ Session 2008 NSY 103 (S. Cherrier) Page 7 / 9

2-a) if (strncmp(buffer,ok_response,strlen(ok_response))==0) write(fd,ok_message,strlen(ok_message)); else write(fd,error_message,strlen(error_message)); return 0; Les architectures des ordinateurs intervenant dans l'échange peuvent différer, notamment sur leurs façons de stocker les mots de plusieurs octets. Dans le cas d'un mot de 32 bits, ceux-ci stokent parfois l'octet de poids fort en fin du mot (on dit que le processeur est gros-boutiste (big-endian)), et dans le cas contraire (octet de poids fort stocké en debut), il est appelé petit-boutiste (littleendian). Si deux ordinateurs utilisant l'un un petit-boutiste l'autre un gros-boutiste communiquent, il y a fort à parier que l'échange sera altéré par cette différence d'organisation. Il faut donc normaliser l'échange des entiers. On utilisera donc toujours les fonctions htonl(), htons(), ntohl() et ntohs() afin de convertir les entiers dans la norme choisie par l'internet (petit-boutiste). 2-b) le processus dispose d'un espace d'adressage, protégé, qui lui est réservé. Il y accède via des adresses logiques, que la MMU traduit en adresses réelles. Cette indirection permet de réorganiser le contenu réel de la RAM sans impacter les processus (il suffit simplement de mettre à jour la table de translation d'adresses pour tenir compte des changements). La mémoire va être découpée en zones, afin d'être mieux gérée, et de pouvoir être réorganisée. Le découpage peut être fait selon deux philosophies : la pagination ou la segmentation. 3-a) La pagination découpe la mémoire en blocs de taille fixe, les pages. L'intérêt du système est que la réorganisation de la RAM est plus simple à réaliser avec des blocs de taille fixe. L'inconvénient est que ce découpage est arbitraire, et ne correspond pas aux besoins logiques du processus. D'où la fragmentation interne La segmentation est une division de la RAM en bloc de taille variable, adaptée aux besoins du processus. La problématique est alors la gestion de la réorganisation, puisqu'avec des blocs de taille variables, il est plus difficile d'optimiser l'occupation, des «trous» risquent d'apparaître, on parle alors de fragmentation externe. Un processus est l'image d'un programme en mémoire centrale. Le processus est identifié par un entier qui lui est propre, unique à un instant t. C'est le PID (le process Identifier). Ce PID est donné par le scheduler (l'ordonnanceur de tâches), et permet ensuite de se référer à ce processus spécifique. Le processus utilise un espace mémoire qui lui est réservé. Cet espace mémoire contient le code binaire correspondant au programme, et diverses autres zones. Parmi celles-ci, on peut remarquer : la pile (un espace dernier entrée premier sorti qui contiendra notamment l'empilement des appels aux sous-programmes (que ce soient les primitives systèmes ou nos propres fonctions) avec l'adresse de retour et l'espace pour les valeurs de retour), le tas (espace dynamique pour stocker des informations, variables, etc), et enfin une zone contenant les variables d'environnement. Les processus sont organisés selon un arborescence père-fils, c'est à dire un arbre n-aire. La racine de cet arbre est le processus initial (init, processus 1). Chaque processus connaît son père (via le PPID, le PID du Parent). En général, le processus fils hérite des principales caractéristiques du Session 2008 NSY 103 (S. Cherrier) Page 8 / 9

processus père. 3-b) Les primitives système offrent la gestion des processus (organisés en arborescence). Les primitives principales sont : fork() : pour dédoubler le processus, c'est la création proprement dite d'un fils, identique en tous points à son père (même contenu, même variables et valeurs, même étape). wait() : le processus se met en attente (très souvent, il attend un signal de son fils) exit() : fin du processus, permet d'envoyer un signal libérateur au père, qui est certainement en attente. exec() : recouvrement, le fils souvent doit faire quelque chose de différent du père. Or, après le fork(), le père et le fis sont absolument identique. Exec() et tous ces dérivés permettront au fils de se spécialiser, de se transformer en autre chose, de «recouvrir» son code binaire par un autre code binaire. 3c) #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <stdio.h> int main(int argc, char **argv) { int i; /* pour le suivi du comptage des arguments */ for (i=1;i<argc;i++) { //Attention, on commence à 1!!! char * cde=argv[i]; // on stocke la commande voulue pid_t p=fork(); if(p==0) { //je suis le fils printf("je suis le fils chargé de faire %s\n",cde); execlp(cde,cde,null); exit(0); //inutile, mais on est jamais trop prudent else { //je suis le père printf("%i se charge du travail\n",p); return 0; Session 2008 NSY 103 (S. Cherrier) Page 9 / 9