Previous Contents Next

8   Corrigé du DS du 11 janvier 2002

La durée de ce contrôle est de deux heures, tous les documents sont autorisés (y compris ordinateurs).

Le barème probable est de 5 points pour les questions de cours, de 5 points pour les questions sur X11 et de 5 points pour chaque exercice de codage.

8.1   Questions de cours sur les sockets

Répondez aux questions suivantes (deux lignes de réponse par question suffisent) :
  1. Citez une interface de programmation réseau qui ne soit pas celle des sockets.
    Principalement on peut citer Remote Procedure Call (RPC) de SUN micro-systems mais il existe aussi Remote Method Invocation (RMI) de java ou encore Transport Layer Interface (TLI) de l'OSI.
  2. Par quoi est définie une socket ?
    Sa famille (exemple AF_INET), son mode (par exemple SOCK_STREAM) et éventuellement le protocole utilisé (dans l'exemple c'est forcement TCP).
  3. Donnez la taille en octets d'une adresse générique de socket.
    Deux octets pour la famille et 14 de remplissage soit 16 octets.
  4. Existe-t-il des structures adresse de socket de taille inférieure à celle de la structure adresse générique de socket ? En existe-t-il de taille supérieure ?
    Non, il n'existe pas de structure adresse de socket de taille inférieure à 16 octets mais il en existe de taille supérieure comme struct sockaddr_un.
  5. Sachant que addr est une variable de type struct sockaddr_in, quel message le compilateur C va afficher en analysant l'instruction bind(s,&addr,sizeof(addr)); ? Corrigez l'instruction pour qu'elle se compile sans problème.
    Le compilateur va générer un message d'avertissement au sujet du typage de &addr. Le prototype de la fonction bind impose un paramètre de type struct sockaddr * et la variable utilisée est de type struct sockaddr_in *. L'instruction correcte est bind(s,(struct sockaddr *)&addr,sizeof(addr));.
  6. Un descripteur de socket Internet en mode connecté est équivalent à quelle autre entité système ? Est-ce encore vrai pour une socket Internet en mode non connecté ?
    Un descripteur de socket Internet en mode connecté est équivalent à un descripteur de fichier. Ce n'est pas le cas en mode non connecté car des données peuvent être supprimées du flux ou dupliquées.
  7. Comment peut-on obtenir un pointeur de fichier à partir d'un descripteur de socket ?
    En utilisant la fonction fdopen.
  8. Quel est le détail important concernant l'initialisation du troisième argument de la fonction accept ?
    Le troisième argument d'accept doit pointer sur un entier initialisé avec la taille de l'espace pointé par le second argument. Cet espace est utilisé pour stocker l'adresse du client.
  9. Peut-on utiliser la fonction connect dans un client manipulant des socketis Internet en mode non connecté ?
    Oui, cela permet de recevoir des paquets UDP ne provenant que d'une machine bien précise.
  10. Que symbolise la peluche que le redon a sorti de son sac en début d'examen ? Un bonus supplémentaire pour ceux qui me donnent son nom.
    Il s'agit de Tux, la mascotte du système d'exploitation Linux.

8.2   Questions sur le protocole X11

Répondez aux questions suivantes :
  1. Donnez une ligne de commande pour afficher un serveur Xnest de la machine choufleur sur le serveur X principal de la machine courge. Attention, vous devez aussi donner la manipulation a effectuer pour autoriser cet affichage.
    Sur la machine courge il faut trouver la clef d'autorisation d'affichage par la commande xauth list et il faut l'insérer sur la machine choufleur par la commande xauth add. Ensuite, sur la machine choufleur, il faut taper :
    choufleur$ Xnest -display courge:0 :1
    
  2. Donnez les commandes à taper pour afficher un xeyes de la machine concombre sur le serveur Xnest lancé à la question précédente. On considère que le serveur Xnest accepte toute connection de client.
    Sur la machine concombre il faut taper :
    concombre$ xeyes -display choufleur:1
    
  3. On suppose que votre programme quémandeur de session XDM s'appelle xdmquery. Son premier paramètre est le nom de machine sur laquelle tourne le serveur de session et le second paramètre est le nom complet du serveur X à prendre en charge (nom de la machine et numéro d'écran). Utilisez ce programme pour que la machine rave prenne en charge le serveur X principal de la machine concombre (il s'agit du serveur concombre:0). Sur quelle machine la ligne de commande doit être tapée ?
    La ligne de commande peut être tapée sur toute machine disposant de la commande xdmquery. La commande à taper est :
    $ xdmquery rave concombre:0
    
  4. Utilisez xdmquery pour que rave prenne en charge le serveur Xnest lancé à la première question.
    La ligne de commande peut être tapée sur toute machine disposant de la commande xdmquery. La commande à taper est :
    $ xdmquery rave choufleur:1
    
  5. La ligne de commande de la question précédente provoque l'envoi de paquets UDP. Quelles sont les machines qui émettent ces paquets UDP ? Pouvez-vous dire sur quels ports ? Quelles sont les machines qui reçoivent ces paquets ? Pouvez-vous dire sur quels ports ?
    Les paquets UDP sont échangés entre la machine rave et la machine sur laquelle est exécuté xdmquery. Cette dernière machine émet ses paquets UDP à partir d'un port utilisateur choisi par le système et reçoit les réponses de rave sur ce même port. La machine rave reçoit des paquets sur le port XDMCP (port 177) et émet ses réponses du même port.
  6. La ligne de commande des deux questions précédentes donne lieu à des flux TCP. Expliquez ce que sont ces flux TCP et donnez les caractéristiques des connexions TCP liées aux flux (c'est à dire les adresses des sockets aux deux bouts de la connexion). Attention n'oubliez pas qu'un serveur Xnest est à la fois un serveur X et un client X.
    Le premier flux TCP concerne la connexion d'un client X de la machine rave sur le serveur Xnest de nom choufleur:1. Il s'agit du client X d'indentification d'utilisateur lancé par le serveur de sessions de rave. Cette connexion TCP a pour origine rave d'un port utilisateur vers le port 6001 de choufleur. Le second flux TCP concerne l'affichage du programme Xnest sur le serveur X courge:0. Cette connexion TCP a pour origine choufleur d'un port utilisateur vers le port 6000 de courge.

8.3   Extraits de code du tutorat

8.3.1   Code générique

Écrivez une fonction sendPacket qui permet d'envoyer un paquet XDMCP et d'attendre pendant quelques secondes une réponse (la fonction attend la réponse mais ne la lit pas). La fonction prend en paramètres le descripteur de la socket d'envoi, la structure d'adresse de socket du serveur XDM et le tampon XDMCP. La fonction ne relance pas le paquet si aucune réponse n'est reçue mais retourne -1 dans ce cas. Le prototype de cette fonction est imposé :
int sendPacket(int ds,                      /* Socket locale */
               struct sockaddr_in adresse,  /* Socket du serveur */
               XdmcpBufferPtr paquet        /* Contient le paquet XDMCP */
               );
Exemple de code convenable

int sendPacket(int ds,                      /* Socket locale */
               struct sockaddr_in adresse,  /* Socket du serveur */
               XdmcpBufferPtr paquet        /* Contient le paquet XDMCP */
               ){
fd_set lecture ;           /* Ensemble de descripteurs en lecture */
struct timeval minuteur;   /* Structure du minuteur */
 
/* Envoyer le datagramme XDMCP */
sendto(ds,paquet->data,paquet->pointer,0,
       (struct sockaddr *)&adresse,sizeof adresse);

/* Attente d'une reponse avec armement d'un minuteur */
FD_ZERO(&lecture); FD_SET(ds,&lecture);
minuteur.tv_sec=MINUTEUR_DUREE; minuteur.tv_usec=0;
select(ds+1,&lecture,NULL,NULL,&minuteur);

/* Calcul du code de sortie */
if(FD_ISSET(ds,&lecture)) return 0; else return -1;
}

8.3.2   Code spécifique

Écrivez la fonction remplissant une structure XdmcpBuffer avec un paquet XDMCP de type QUERY. Le prototype de cette fonction est imposé :
XdmcpBufferPtr buildQuery(void);
Vous utiliserez obligatoirement la fonction XdmcpWriteARRAYofARRAY8.
Exemple de code convenable

XdmcpBufferPtr buildQuery(void){
XdmcpBufferPtr buffer;
XdmcpHeader header;
ARRAYofARRAY8 array;

/* Allocation du tampon XDMCP */
buffer=allocXDMCPBuffer();

/* Ecriture de l'entete XDMCP */
header.version=XDM_PROTOCOL_VERSION;
header.opcode=(CARD16)QUERY;
header.length=1;
XdmcpWriteHeader(buffer,&header);

/* Ecriture des champs additionnels */
array.length=0;
array.data=NULL;
XdmcpWriteARRAYofARRAY8(buffer,&array);

return buffer;
}
Écrivez la fonction affichant une structure ARRAY8 sous forme de chaîne de caractères (fonction pouvant être utilisée pour le décodage des paquets WILLING par exemple). Le prototype de cette fonction est imposé :
void displayString(ARRAY8 array);
Exemple de code convenable

void displayString(ARRAY8 array){
int i;
for(i=0;i<array.length;i++) printf("%c",array.data[i]);
printf("\n");
}

Previous Contents Next