J’écris un serveur / client simple en c, où le serveur stocke temporairement le message du client et le récupère lorsque le client le demande.
Le problème est que lorsque le client reçoit un message du serveur, le tampon agit un peu bizarre. Tout ce que j’ai fait est lu autant que recevoir du serveur et l’imprimer à l’écran, mais d’une manière ou d’une autre, la mémoire tampon a été écrasée plus que la taille maximale de la mémoire tampon
dans le client
while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0) { if(byteRead <= 0) break; printf("%s", buffer); }
où MAXBUF est égal à 256. Il contient des déchets alors j’ai examiné la taille de la chaîne dans le tampon et, de manière surprenante,
printf("%d READ vs %d buffer strlen \n", byteRead, strlen(buffer))
montrez-moi que byteRead vaut 256 mais que la longueur de chaîne du tampon est de 262.
Une idée??
Ps côté serveur, il lit correctement le fichier et l’envoie sur socket.
recv
ne place pas de terminateur nul à la fin de la chaîne (alors que printf
%s
suppose qu’il en existe un).
Vous devez utiliser byteRead
pour déterminer la longueur de la chaîne. Ajoutez un terminateur nul si vous souhaitez utiliser une fonction telle que printf
, mais assurez-vous que votre tampon dispose de l’espace nécessaire même pour une lecture de taille maximale.
Le problème ici est que la buffer
n’est pas terminée par NULL par recv()
. En fait, recv
ne place que les données de socket brutes dans la mémoire tampon. S’il reçoit 256 octets de données, tout ce qui vient après peut être composé de caractères nuls (comme sur votre serveur) ou autre chose (comme sur votre client). C’est un artefact de l’exécution du programme, pas de la façon dont vous l’avez programmé.
Le moyen le plus simple et le plus rapide de résoudre ce problème:
MAXBUF + 1
buffer
avec la taille MAXBUF + 1
. Le +1 sera pour un caractère NULL supplémentaire. printf
, ajoutez un caractère null dans buffer[bytesRead]
. Donc tout dit:
buffer = malloc((MAXBUF + 1) * sizeof(char)); // NEW while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0) { if(byteRead <= 0) break; else { buffer[bytesRead] = '\0'; // NEW printf("%s", buffer); } }
Oui.
strlen () recherche le terminateur NULL le plus proche, comme dans une chaîne C conventionnelle.
recv () n’a rien à voir avec le terminateur null et n’en appendait pas. Ainsi, l’appel strlen est erroné et peut même bloquer votre programme par une lecture non autorisée.