C'est généralement le résultat de quelque chose comme :
/* BAD CODE */
const char* ack = "ACK";
err = write( sockfd, ack, strlen( ack )); /* sender */
/* ... */
char buf[SOME_SIZE]
readb = read( sockfd, buf, SOME_SIZE ); /* receiver */
printf( "%s", buf );
Le problème avec le code ci-dessus est que l'expéditeur n'écrit que trois (3) octets sur le socket. Cela n'inclut pas le terminateur zéro de la chaîne de caractères. Ensuite, le récepteur reçoit les données et ne vérifie pas du tout la valeur de retour de l'appel système ou/et imprime aveuglément les données reçues. Le site printf
imprimera tout jusqu'à ce qu'il trouve un octet de valeur nulle en mémoire.
Edit :
D'après vos commentaires, je pense que vous supposez que l'on send(2)
sur un socket TCP devrait donner lieu à une recv(2)
à l'autre extrémité avec le nombre d'octets correspondant (je suppose que c'est ce que vous voulez dire par "le nombre d'octets lus est faux"). Ce n'est pas le cas avec TCP. Vous devez traiter le socket comme un flux qui peut vous donner des morceaux de taille arbitraire de ce qui vous a été envoyé. C'est à vous de les assembler et de reconnaître les limites des messages de l'application. Cela signifie simplement que vous lisez toujours à partir d'une socket dans une boucle (sans compter les conceptions non-bloquantes avec select(2)
et les amis - c'est un autre sujet).
Deux conceptions acceptées de protocole au niveau de l'application sont :
- Communiquer via des messages prédéfinis de longueur fixe - de cette façon, vous lisez jusqu'à ce que vous obteniez ce nombre d'octets du socket. C'est simple.
- Inclure le type de message et/ou la longueur du message dans le message lui-même - cela se fait généralement avec un en-tête de message de longueur fixe qui est suivi d'une charge utile de message variable. Lisez jusqu'à ce que vous obteniez l'en-tête complet, puis changez/dispatch/continuez la lecture en fonction du type/longueur.
N'oubliez pas endiveté - des réseaux comme ordre des octets du réseau .