:: Enseignements :: Master :: M1 :: 2016-2017 :: Programmation d'applications réseaux ::
[LOGO]

TCP non bloquant


Exercice 1 - Mini additionneur TCP non bloquant

On souhaite écrire un serveur qui accepte de multiples clients en non-bloquant et permet d'effectuer l'addition de deux entiers pour chaque client.

Plus précisément, le client envoie deux int en Big Endian, puis ferme la connexion en écriture. Le serveur renvoie un int en Big Endian, valant la somme des deux entiers reçus, puis il ferme la connexion. Par exemple, si le client envoie 7 et 10, le serveur renverra 17.

Pour simplifier, on vous donne le code du client, qui demande 2 entiers au clavier, les envoie au serveur et attend la réponse du serveur.

  1. Écrire le code du serveur ServerSumOneShot non bloquant. Il n'est pas nécessaire de vérifier si le client a bien fermé la connexion après l'envoi des deux int.

    Pour vous aider, vous pouvez utiliser le code suivant comme point de départ. Pour cet exercice, vous stockerez dans le champ attachement un ByteBuffer de taille 8.

    Que se produirait-il si, au moment d'écrire la somme vers un client, le serveur ne pouvait écrire que 2 des 4 octets lors d'une tentative d'écriture non bloquante? Même s'il est improbable dans notre exemple, prévoyez ce cas dans votre code.

    Comment faut-il traiter les exceptions levées dans les méthodes doRead, doWrite et doAccept ?

  2. Adapter votre serveur en un serveur ServerSumMulti pour qu'il puisse traiter une succession de somme. Vous pourrez tester votre serveur avec le jar ClientTestServerMulti.jar.
    java -jar ClientTestServerMulti.jar localhost 7777
        

    Si tout est correct, vous devriez voir, après une dizaine de secondes, un affichage du type:
    Client 2 : finished receiving
    Client 2 : waiting for server to close connection
    Client 2 : finished writing
    Client 4 : finished receiving
    Client 4 : waiting for server to close connection
    Client 4 : finished writing
    Client 0 : finished receiving
    Client 0 : waiting for server to close connection
    Client 0 : finished writing
    Client 1 : finished receiving
    Client 1 : waiting for server to close connection
    Client 1 : finished writing
    Client 3 : finished receiving
    Client 3 : waiting for server to close connection
    Client 3 : finished writing
    Everything is OK.     
     

Exercice 2 - Serveur Echo

Ecrivez un serveur Echo en non-bloquant. Le serveur ServerEcho renvoie tous les octets écrits par le client. Il ferme la connection après que le client ait fermé la connection (et après que toutes les données aient été envoyées).

Pour ce serveur, vous utiliserez en attachment une classe contenant un boolean et un ByteBuffer. Le boolean servira à mémoriser si le client a fermé la connection.

Une fois que votre serveur semble fonctionner, testez le avec le client ci-dessous, qui envoie en boucle l'octet 1 puis l'octet 2 et dans un autre thread affiche le numéro des octets recus.

L'intérêt de ce client est qu'il lit "lentement" et donc, à terme, ralentit le rythme d'écriture du serveur (à cause du contrôle de flot effectué par TCP). Ainsi, en consultant (par la commande top en linux) les ressources CPU utilisées par votre serveur, vous devrez constater qu'elles sont très limitées. Si le serveur consomme beaucoup de CPU, c'est par exemple parce qu'il tente d'écrire alors que ce n'est pas possible (il fait alors une forme d'attente active): le principe des entrées sorties non bloquantes est précisément d'éviter ces comportements.

Exercice 3 - Tuer les clients inactifs

Lorsque un client a été accepté par le serveur mais qu'il n'est plus actif depuis une durée jugée suffisante (TIMEOUT) on aimerait que le serveur mette fin à cette connexion. Faites évoluer votre serveur Echo non bloquant pour qu'il implémente cette fonctionnalité.

Exercice 4 - Duplicateur

On souhaite écrire un serveur TCP non bloquant qui rend le service suivant: pour chaque client accepté, sur le flot de lecture, lorsque 2 octets consécutifs ont des valeurs croissantes qui se suivent (comme par exemple 65 et 66), alors le serveur renvoie au client le premier de ces deux octets. Par exemple:
Si le serveur reçoit : 68 65 67 68 65 65 66 67 67 68 69 70 71 65
alors il renvoit     :       67       65 66    67 68 69 70

Pour ce serveur, vous utiliserez comme attachment une classe contenant deux ByteBuffer pour in et out.

Dans un premier temps, vous pouvez tester votre serveur avec nc. Par exemple si votre serveur est lancé sur le port 7778. Vous devriez observer:
$ nc localhost 7778
ABBBCABBCDE^D
ABABCD

Une fois que votre serveur semble fonctionner, testez le avec le client ci-dessous, qui envoie en boucle l'octet 1 puis l'octet 2 et dans un autre thread affiche le numéro des octets recus.

Outre le fait que le client ne doit recevoir que des octets 1 et en permanence, l'intérêt de ce client est qu'il lit "lentement" et donc, à terme, ralentit le rythme d'écriture du serveur (à cause du contrôle de flot effectué par TCP). Ainsi, en consultant (par la commande top en linux) les ressources CPU utilisées par votre serveur, vous devrez constater qu'elles sont très limitées. Si le serveur consomme beaucoup de CPU, c'est par exemple parce qu'il tente d'écrire alors que ce n'est pas possible (il fait alors une forme d'attente active): le principe des entrées sorties non bloquantes est précisément d'éviter ces comportements.

Exercice 5 - Serveur Long Sum

Ecrivez un serveur non-bloquant pour le protocole long somme de longs que nous avons vu dans les TPs précédents. Le client envoie un INT avec le nombre d'opérandes puis chacunes des opérandes qui sont des LONGs. Le serveur renvoie la somme de toutes les opérandes recues.