Estoy trabajando en un programa confiable de transferencia de archivos que usa UDP. (. Para un curso en la red de la computadora)¿Las llamadas sucesivas a recvfrom() pierden datos?
Mi pregunta es la siguiente - así, tenga en cuenta este escenario:
remitente tiene (por ejemplo) 12 bytes de datos para enviar. Por lo que el emisor realiza esta llamada:
sendto(fd, &buf, 12, 0, (struct sockaddr *)&cliaddr,sizeof(cliaddr));
Esto envía los 12 bytes de datos de manera fiable. Los primeros 4 bytes de estos datos pasan a ser un campo de "longitud de mensaje". En este caso, los primeros 4 bytes pueden tener el valor 0x0000000C
El receptor desea leer los primeros 4 bytes utilizando recvfrom(). Al ver que el tamaño del segmento es de 12 bytes, quiere leer los 8 bytes restantes. Por lo que el receptor podría tener este aspecto:
/* 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);
Cuando ejecuta este código, puede recibir los primeros 4 bytes sin ningún problema. Pero cuando trato de buscar los datos restantes, esos datos parecen estar perdidos. En mi salida, estoy recibiendo basura, parece que una parte del siguiente 12 bytes que el remitente está enviando a() - ing.
¿Este comportamiento es esperado? Es decir, si una sola llamada recvfrom() no lee todos los datos que se enviaron, ¿no se garantiza que esos datos (los 8 bytes restantes) estén disponibles para mí?
Parece que el método estándar para enviar un encabezado de segmento (incluido su tamaño), seguido de la carga útil, no funciona. ¿Eso significa que tengo que enviar 2 segmentos separados, uno que solo contiene información de encabezado y luego un segundo segmento con la carga útil? O solo estoy usando estas llamadas al sistema de forma incorrecta (o hay una bandera o setsockopt() que me falta?)
El punto es que UDP es un protocolo de estilo de paquete, no un protocolo de estilo de canal. Por lo tanto, debe proporcionarle todo el paquete de una vez, para que pueda saber dónde termina el paquete.De lo contrario, no tendrías ni idea de qué estaba pasando realmente. –