Je travaille sur un programme de transfert de fichiers fiable qui utilise UDP. (. Pour un cours en réseau informatique)Les appels successifs à recvfrom() perdent des données?
Ma question est - bien, pensez à ce scénario:
expéditeur a (par exemple) 12 octets de données à envoyer. L'expéditeur exécute donc cet appel:
sendto(fd, &buf, 12, 0, (struct sockaddr *)&cliaddr,sizeof(cliaddr));
Ceci envoie les 12 octets de données de manière non fiable. Les 4 premiers octets de ces données se trouvent être un champ "longueur de message". Dans ce cas, les 4 premiers octets peuvent avoir la valeur 0x0000000C
Le récepteur veut lire les 4 premiers octets en utilisant recvfrom(). Voyant que la taille du segment est de 12 octets, il veut lire les 8 octets restants. Ainsi, le récepteur pourrait ressembler à ceci:
/* read the segment size */ recvfrom(sockfd,&buf,4,0,(struct sockaddr *)&cliaddr,&len); /* do some arithmetic, use bzero(), etc */ /* read the rest of the data */ recvfrom(sockfd,&buf,8,0,(struct sockaddr *)&cliaddr,&len);
Lorsque j'exécute ce code, je peux recevoir les 4 premiers octets sans problème. Mais quand j'essaye d'aller chercher les données restantes, ces données semblent être perdues. Dans ma sortie, je reçois des déchets - il ressemble à une partie des prochains 12 octets que l'expéditeur est sendto() - ing.
Est-ce que ce comportement est attendu? C'est-à-dire, si un seul appel recvfrom() ne lit pas toutes les données envoyées, n'est-il pas garanti que ces données (les 8 octets restants) sont disponibles pour moi?
Il semble que la méthode standard d'envoi d'un en-tête de segment (y compris sa taille), suivie de la charge utile, ne fonctionne pas. Est-ce que cela signifie que j'ai besoin d'envoyer deux segments séparés - un qui ne contient que des informations d'en-tête, et un deuxième segment avec la charge utile? Ou suis-je juste en utilisant ces syscalls incorrectement (ou est-il un drapeau ou setsockopt() que je suis absent?)
Le point est que UDP est un protocole de style de paquet, pas un protocole de style pipe. Ainsi, il doit vous donner le paquet entier en un coup, de sorte que vous puissiez savoir où le paquet commence une fin.Sinon, vous n'auriez aucune idée de ce qui se passait vraiment. –