Socket recv incomplet

Utilisateur anonyme -  
Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,

Voila j'ai un programme qui utilise des sockets
et je doit recevoir un fichier assez gros 2Mo
je problème c'est que je ne voudrai pas mettre un buffer de 2Mo
Mais que ma fonction reçoivent les données jusqu'à ce qu'il n'y en ai plus

y a t'il une fonction qui permet de savoir si il reste des données a lire sur ma socket ?

Merci

14 réponses

  1. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
     
    un peut tordu.
    Je pense que si tu fait un buffer de taille x, tu fait une boucle sur les recv, et tant que recv te renvoi x comme taille lu, alors il reste des données à lire.
    Je ne suis pas certain, mais ça peut fonctionner.
    0
  2. Utilisateur anonyme
     
    ici mon fichier fais 2Mo
    la il doit en télécharger plusieurs
    qui n'ont pas tous la même taille
    et on ne connais pas cette taille a l avance
    donc je trouve pas sa si tordu si ?
    ou s il y a un moyen plus simple ?
    0
  3. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
     
    non, pas tordu au sens purement algorithmique, mais chiant à faire en socket.
    Pour des données de taille variable, soit tu fais comme je t'ai dit, en testant le recv.
    Sinon, il y a d'autres technique. Récupérer la taille du fichier et envoyer au client. Donc, tu fait un recv qui récupère la taille des données, tu dimensionne ton buffer, tu récupères les données.
    Sinon, tu fait un mini protocole : tu reçoit les données, demandes au serveur s'il y en a d'autre, soit il répond non et c'est fini, soit il répond oui et tu reçoit un autre paquet de données.
    Ce ne sont que des idées qui me viennent sur le vif, mais il doit y a voir d'autres solutions.
    0
  4. Utilisateur anonyme
     
    ok merci je vais testé plusieurs de ces solutions je te tiens au courant =)
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Utilisateur anonyme
     
    Alors j ai essayer plusieurs chose
    premièrement il m est impossible de connaitre la taille du fichier car il sont télécharger via un site donc via HTTP. et sinon ma boucle de recv bug un peu
    0
  7. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
     
    pour connaitre la taille d'un fichier :
    https://forum.hardware.fr/hfr/Programmation/taille-fichier-sujet_15390_1.htm
    C'est sur que si au moment où le serveur ouvre le fichier celui-ci n'est pas complet ça complique l'affaire.
    Je pense à un truc, si tu fait sous windows, il me semble qu'il y a un truc à la con qui stoppe l'envoie des des données ou leur réception lorsque l'on tombe sur des retours à la ligne ou des zéros.
    Met ton code, on y verra plus clair s'il bug.
    0
  8. Utilisateur anonyme
     
    Voici le code de la fonction qui recupere les info

    std::string tHTTP::ReceiveDATA(int Descripteur)
    {
        char Buffer[1024];
        char *DataRecu;
        int ResultRecv = recv(Descripteur, Buffer, sizeof(Buffer),0);
        if (ResultRecv < 0)
        {
            std::cout << " [*] ERR : Reception des donnees impossible " << std::endl;
            perror("recv");
        }
        else
        {
                  DataRecu = new char[strlen(Buffer) + 1];
                  strcpy(DataRecu,Buffer);
        }
    
        std::cout << " [*] VAR : Descripteur = " << Descripteur << std::endl;
        std::cout << " [*] VAR : Data Recu = " << DataRecu << std::endl;
    
        std::string result = DataRecu;
        return result;
    }
    0
  9. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
     
    Je ne comprend pas, tu n'as pas de boucle...
    Tu transmet bien des chaines de caractères ?
    compare strlen(Buffer) et ResultRecv , ils doivent avoir la même taille.

    Sinon, tu peut convenir que lorsque le serveur a terminé de t'envoyer le fichier il emet un mot particulier qui terminera la transmission.
    0
  10. Utilisateur anonyme
     
    oui je transmet des chaine de caractère
    j avais en effet essayer avec une boucle mais sa ne marchai sa terrible

    et pour le mot particulier je ne pense pas que sa soit possible les fichier sont récupérer sur un serveur Web donc par HTTP.

    et en effet strlen(Buffer) et ResultRecv on la même taille
    mais je ne vois pas quoi en faire ? les mettre en tant que condition dans ma boucle ?
    0
  11. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
     
    en fait, tu veux dire en disant HTTP que tu ne code pas le serveur. C'est ça ?
    tu peut récupérer la taille d'un fichier avec les requetes http://www.siteduzero.com/tutoriel-3-35613-les-requetes-http.html#ss_part_3
    Sinon, une boucle du genre :
     int ResultRecv = recv(Descripteur, Buffer, sizeof(Buffer),0);
    while(ResultRecv==1024)
         ResultRecv = recv(Descripteur, Buffer, sizeof(Buffer),0);
    
    0
  12. Utilisateur anonyme
     
    tien voila ce que j ai fais :

    std::string tHTTP::ReceiveHTML(int Descripteur)
    {
        char Buffer[1024];
        char *DataRecu;
        std::string DataFinal = "";
        int continuer = 1;
        while(continuer == 1)
        {
            int ResultRecv = recv(Descripteur, Buffer, sizeof(Buffer),0);
            if (ResultRecv < 0)
            {
                std::cout << " [*] ERR : Reception des donnees impossible " << std::endl;
                perror("recv");
            }
            else
            {
                      DataRecu = new char[strlen(Buffer) + 1];
                      strcpy(DataRecu,Buffer);
                      std::string result = DataRecu;
    
                      DataFinal = DataFinal + result;
    
            }
    
            if (ResultRecv != strlen(Buffer))
                continuer = 0;
        }
    
        return DataFinal;
    }
    


    Par contre je ne reçoit toujours pas toute une page.
    0
  13. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
     
    bon, en effet, si tu ne fait pas le serveur, il faut surement passer par une socket non bloquante...
    Win ou Linux ? Sous Linux, je peut te donner quelques liens.
    0
  14. Utilisateur anonyme
     
    Oui je veux bien tes liens
    Oui oui c est sur linux.
    0
  15. Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 331
     
    pour avoir une socket non bloquante, il faut utiliser fcntl http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man2/fcntl.2.html avec l'argument O_NONBLOCK
    Ensuite, tu peux utiliser select pour attendre les premières données normalement. http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man2/select.2.html
    Ensuite, il faut combiner le tout avec un timeout.
    Je ne peut pas plus t'aider, je ne me suis jamais aventurer là dedans, je préfère trouver d'autre solutions (dans ton cas, j'utiliserai Qt et ses fonctions HTTP). Mais en faisant des recherche supplémentaire avec ces mots clefs plus ceux que tu trouvera dans les liens, tu devrais pouvoir t'en sortir.
    0