3 votes

Données du socket corrompues pendant le transfert TCP/IP

Lorsque j'envoie des données sur un socket TCP-IP pré-connecté, je constate que les données sont corrompues.

Exemple :

La station 1 envoie des données à la station 2. J'ai imprimé les données, avant l'envoi (à S1) et après la réception (à S2). Voici le message :

S1 : Les données envoyées sont ACK
S2 : Les données reçues sont AC

Je ne sais pas quel est le problème. J'ai même effacé le char-buffer avant d'envoyer les données (à S1) et avant de les recevoir (à S2).

Tout conseil ou toute information sur ce qui précède serait d'une grande utilité.

4voto

Nikolai N Fetissov Points 52093

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 .

2voto

user508 Points 11

Etes-vous sûr de recevoir tout le message en une seule fois ? Puisque le TCP est un protocole basé sur le flux, les données que vous lisez sur la Station2 peuvent se présenter sous forme de petits morceaux de données. Vous devez regarder combien de données la fonction recv() a mis dans votre tampon.

Par exemple, votre premier appel à recv() peut donner "AC". et ensuite, l'appel suivant peut vous donner le reste des données "K".

0voto

Du côté client, j'envoie une chaîne de caractères à un socket :

char message[200];

/*string to be sent*/
strcpy(message, "Hi PQRS, How are you!?");

/*send string to server's socket*/
if( send(socket_desc , message , strlen(message)+1 , 0) < 0)
    {
        puts("Send failed");
        return 1;
    }
puts("Data Sent\n");

Remarquez comment je passe

strlen(message) + 1

pour prendre en compte le délimiteur, c'est-à-dire ' \0 ' au lieu de

strlen(message)'

Il garantit la fin de la chaîne et qu'aucune donnée supplémentaire n'est ajoutée.

Cela fonctionne quelle que soit la taille du tableau de caractères côté serveur, à condition qu'il soit égal ou supérieur à la chaîne entrante afin de pouvoir l'accueillir.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X