Question

Je suis en train de recevoir certains fichiers via des sockets en C. Mais le serveur me envoie des paquets de 64 octets pour un fichier 1000000 octets par exemple et je reçois environ 999902 octets sur le fichier de destination.

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

Quand il est utilisé par un socket TCP / IP locale il fonctionne, mais pas dans une connexion lente. Je vois à travers le débogage que je reçois beaucoup de 64 morceaux d'octets et un morceau de 30 octets près EOF. Je sais que vous pouvez obtenir moins d'octets sur lecture () depuis le retour de l'appel lorsque des données (> 1 octet) est disponible. Mais cette condition ne doit pas être attrapée par le temps? Devrait revenir lorsque n == 0, qui est plus de données (EOF).

Thx pour votre aide.

(EDIT)

Envoi code comme suit:

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

Je sais que les deux lecture () et write () peut retourner N

(EDIT II)

Testé avec une source C avec 10673 octets, reçoit 10575 sans corruption, sauf que le fichier de destination MANQUE les 98 premiers octets !!!

Était-ce utile?

La solution

Le code d'envoi fournies ne tient pas compte du fait que écrire () (ou envoyer ()) sur une prise de courant ne soit pas obligé d'écrire l'ensemble tampon.

write () / send () pourrait décider d'écrire écrire partiellement ou pas du tout si le sous-système sous-jacent refuse de recevoir plus de données (par exemple, le sous-système de réseau peut avoir une file d'attente pour les données pour envoyer et cette file d'attente est déjà plein). C'est très probable une connexion lente.

Le côté émetteur doit vérifier la valeur de retour d'écriture () pour détecter le volume de données a été effectivement écrit et ajuster en conséquence.

Ecrire devrait se faire en quelque sorte comme ceci:

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 );
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top