Pregunta

Estoy tratando de recibir algún archivo a través de tomas en C. Sin embargo, el servidor me envía paquetes de 64 bytes de un archivo millón de bytes, por ejemplo, y me sale aproximadamente 999902 bytes en el archivo de destino.

while ((n = read(sd, buffer_in, BUFSIZE ))) //  BUFSIZE = 64 
{
    if(n<0)
    {
       printf("Fail.\n");
       fclose(archivo);
       return -1;
    }

    if(fwrite(buffer_in, n, 1, f) !=1 ) 
    { 
       printf("fwrite error.\n");
       fclose(archivo);
       return -1;
    }

    bytes+=n;
}

printf("We received %d bytes",  bytes);

Cuando se utiliza a través de un socket TCP / IP local que funciona, pero no en una conexión lenta. Veo a través de la depuración que consigo una gran cantidad de trozos 64 bytes, y un trozo de 30 bytes cerca EOF. Sé que se puede obtener en menos bytes de lectura (), ya que se devuelve la llamada cuando cualquier dato (> 1 byte) está disponible. Sin embargo, esta condición no debe ser atrapado por el tiempo? Debe regresar cuando n == 0, que hay más datos (EOF).

Thx por su ayuda.

(EDIT)

Envío de código como sigue:

while (n=read(file_fd, buffer, BUFSIZE))
{
   write (sdaccept, buffer, n)
}

Sé que tanto read () y write () puede devolver N

(EDIT II)

Probado con una fuente de C con 10673 bytes, recibe 10575 sin corrupción, con la excepción de que el archivo de destino carece de los primeros 98 bytes !!!

¿Fue útil?

Solución

El código proporcionado enviar ignora el hecho de que escribir () (o enviar ()) en un socket no está obligado a escribir todo el búfer.

write () / send () podría decidir a escribir de manera incompleta o no escribir en absoluto si el subsistema subyacente se niega a recibir más datos (por ejemplo, el subsistema de red puede tener una cola para los datos a enviar y esta cola ya está completo). Eso es altamente probable que en una conexión lenta.

El lado emisor debe comprobar el valor de retorno de escritura () para detectar la cantidad de datos que se ha hecho por escrito y ajustar en consecuencia.

escritura debe hacerse de alguna manera como esto:

int readAmount;
while( readAmount = read(file_fd, buffer, BUFSIZE) > 0 )
{
    int totalWritten = 0;
    do {
       int actualWritten;
       actualWritten = write (sdaccept, buffer + totalWritten, readAmount - totalWritten);
       if( actualWritten == - 1 ) {
           //some error occured - quit;
       }
       totalWritten += actualWritten;
    } while( totalWritten < readAmount );
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top