Socket recv incomplet

Utilisateur anonyme -  
Char Snipeur Messages postés 9813 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

Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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
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
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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
Utilisateur anonyme
 
ok merci je vais testé plusieurs de ces solutions je te tiens au courant =)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
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
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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
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
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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
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
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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
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
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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
Utilisateur anonyme
 
Oui je veux bien tes liens
Oui oui c est sur linux.
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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