Domanda

Sto cercando di ricevere qualche file tramite prese in C. Ma il server mi manda pacchetti da 64 byte per un file 1000000 byte per esempio e ottengo circa 999902 byte sul file di destinazione.

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);

Quando viene utilizzato tramite un socket TCP / IP locale funziona, ma non in una connessione lenta. Vedo attraverso il debug che ho un sacco di 64 blocchi di byte, e un pezzo di 30 byte nei pressi di EOF. So che si può ottenere meno byte su read () in quanto la chiamata ritorna quando tutti i dati (> 1 byte) è disponibile. Ma questa condizione non dovrebbe essere catturato dal tempo? Deve restituire quando n == 0, che sono più dati (EOF).

Thx per il vostro aiuto.

(EDIT)

L'invio di codice come segue:

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

So che entrambi read () e write () può restituire N

(EDIT II)

Testato con una sorgente C con 10673 byte, riceve 10575 senza corruzione, se non che il file di destinazione manca dei primi 98 byte !!!

È stato utile?

Soluzione

Il codice di invio fornito ignora il fatto che scrivere () (o send ()) su un socket non è obbligato a scrivere l'intero buffer.

write () / send () potrebbe decidere di scrivere parzialmente o non scrivere affatto se il sottosistema sottostante rifiuta di ricevere più dati (ad esempio, il sottosistema di rete può avere una coda per i dati da inviare e questa coda è già pieno). Questo è altamente probabile una connessione lenta.

Il lato invio dovrebbe controllare il valore di ritorno di write () per rilevare la quantità di dati è stato effettivamente scritto e regolare di conseguenza.

Scrivi dovrebbe essere fatto in qualche modo simile a questo:

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 );
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top