La méthode de lecture des exemples, utilisés dans ce chapitre, fonctionne parfaitement avec un client tel que la version Linux de la commande telnet, car ce client envoie (par défaut) ligne par ligne, dans le canal de communication TCP, ce qui est saisi. Par contre, cela ne fonctionne pas avec la version Windows de la commande telnet, car cet autre client envoie (par défaut) caractère par caractère au fur et à mesure de la saisie.
Il faut partir du principe qu'une réception d'un flux TCP peut être fragmentée en plusieurs morceaux de taille (tous de taille inférieure au tampon passé à la fonction read). Une ligne doit donc être lue via une boucle de read qui remet bout à bout chaque morceau lu jusqu'à réception du caractère de fin de ligne.
Pour être complet, il faut également prévoir le cas où on commencerait à recevoir quelques caractères de la ou des lignes suivantes qu'il convient donc de conserver et d'isoler de la ligne précédente.
Sans gestion de stream | Avec gestion de stream |
---|---|
En multi-processusVoir les solutions améliorées du TP n°2 question n°2. En multi-threadVoir les solutions améliorées du TP n°2 question n°3. En mono-tâcheVoir les solutions améliorées du TP n°2 question n°4. |
En langage C, il existe le type FILE défini dans stdio.h qui offre plusieurs possibilités dont les suivantes :
On peut associer à un descripteur de fichier une gestion de stream via la fonction fdopen(int fd, const char *mode) qui retourne un pointeur vers un FILE si l'association s'est faite avec succès. Le premier argument de la fonction est le descripteur de fichier. Le second argument est une chaine de caractère indiquant le mode d'utilisation, celui-ci devant être compatible avec le fonctionnement du descripteur de fichier. Exemple : #include <stdio.h> void communication_serveur(int fd) { FILE *stream; char buffer[1024]; stream=fdopen(fd,"rb"); if (stream!=NULL) { while (!feof(stream)) { fgets(buffer,sizeof(buffer),stream); write(fd,buffer,strlen(buffer)); } } } Remarque : Même si cette méthode peut être agréable à utiliser et fonctionne très bien en mono-client et en multi-client quand on utilise le multi-processus ou le multi-thread, il ne faut pas perdre de vue que les fonctions, de lecture de stream, telles que fgets sont, par défaut, bloquantes car elles utilisent des boucles de read et peuvent donc poser des problèmes dans une programmation multi-client/mono-tâche utilisant la fonction select. |