Test TP n° 1 de réseau

(21 décembre 2001 – durée : 2h)

 © D. Mathieu   mathieu@romarin.univ-aix.fr  M. Laporte et C.Pain-Barre
I.U.T.d'Aix en Provence - Département Informatique
Créé le17/12/2001 - Dernière mise à jour : 17/12/2001

Tout document autorisé

Sommaire

Connexion non bloquante
Connexions multiples

I - Connexion non bloquante

    Rappelons qu'une application cliente est bloquée dans l'appel de la fonction connect() pendant tout le temps que le système (plus précisément TCP) effectue la "triple poignée de mains" avec le serveur, ou plus précisément jusqu'à ce que TCP reçoive l'acquittement ACK du paquet de synchronisation SYN qu'il a émis. Cela peut aller de quelques milli-secondes (sur un réseau local LAN) jusqu'à quelques secondes sur un grand réseau (WAN). Comme il a été indiqué par ailleurs au cours des TPs, TCP arme lui-même un sablier, et l'appel à la fonction connect() échoue (renvoie -1 avec errno == ETIMEDOUT) lorsque le délai arrive à expiration. Malheureusement, ce délai est souvent trop long et l'utlisateur peut vouloir le raccourcir.

    Dans le TP consacré aux sockets connectées Internet, nous avons montré comment résoudre ce problème au moyen d'une alarme gérée à l'intérieur de la fonction ClientConnectSockIn().

    Il existe une autre possibilité grâce à la fonction connect() non bloquante : c'est l'objet de cet exercice.

    Comme pour tous les autres supports (pipes, terminaux, etc), toutes les opérations sur un descripteur peuvent être rendues non bloquantes au moyen de la fonction fcntl(), comme cela a été étudié dans l'exo_02 du TP consacré à l'étude du modèle Producteurs/Consommateurs. Dans le cas d'un socket descriptor, l'appel à la fonction connect() n'est plus bloquante, elle renvoie 0 en cas de succès (en particulier lorsque le serveur est sur la même machine que le client), et -1 en cas d'échec, avec errno == EINPROGRESS.

    D'autre part, TCP informe l'application du succès ou de l'échec de la connexion par un événement d'écriture. En d'autres termes, si le client ajoute le descripteur de socket à un masque d'écriture et s'il appelle la fonction select(), il est débloqué par cet événement. La fonction select() permettant l'utilisation d'un sablier, cette solution est une alternative à celle qui a été proposée.

Travail demandé

    N'indiquer ni les fichiers inclus, ni les espaces de noms utilisés

    Dans le fichier nsNet.cxx, réécrire le corps de la fonction nsNet::ClientConnectSockIn() (le profil n'est pas modifié) selon les indications suivantes : Corrigés : nsNet.cxx

Sommaire

II - Connexions multiples

    Dans certaines circonstances, une application client doit établir plusieurs connexions. C'était le cas par exemple d'un navigateur (avant la nouvelle version du protocole http) qui recevait une home page Html, l'analysait, et lançait autant de connexions qu'il y avait de liens sur des fichiers à rapatrier (fichiers textes .html pour les frames, fichiers images .gif,  etc.).

    Plutôt que d'effectuer ces différentes connexions séquentiellement, il est plus efficace de les lancer en parallèle, sans bloquage, et d'attendre ensuite jusqu'à un délai maximal. C'est le but de cet exercice.

Travail demandé

    N'indiquer ni les fichiers inclus, ni les espaces de noms utilisés

    Dans le fichier nsNet.cxx, écrire le corps de la fonction nsNet::ClientMultiConnectSockIn()de profil suivant :
 
void ClientMultiConnectSockIn (int NbConnect,
                               int                sd          [],
                               ::in_addr          Adresse     [],
                               unsigned short int Port        [],
                               int                CodErr      [],
                               unsigned TimeOut = 0);
    Contrairement au premier exercice, aucune exception ne sera levée dans les cas à problème, seul un code d'erreur sera positionné :     Contrairement à l'exercice précédent, l'appel à la fonction Select() est dans une boucle qui se termine lorsqu'il n'y a plus de connexions en suspens, ou lorsque le délai est atteint (on supposera que le délai passé à Select() contient en sortie le reste de temps non écoulé, qui sera utilisé pour réarmer le sablier à la boucle suivante).

    Le masque d'écriture utilisé dans l'appel de Select() est construit à partir des sockets descriptors dont la connexion est en suspens.

Corrigés : nsNet.cxx

Sommaire

© D. Mathieu    mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique