Telechargeur [dev-c++]

Soyez le premier à donner votre avis sur cette source.

Vue 11 160 fois - Téléchargée 1 742 fois

Description

C'est un programme utilisant la librairie wininet, et qui permet de télécharger
(ou de reprendre le téléchargement) d'un fichier sur les sites en http ou ftp avec authentification si nécessaire.
J'ai réutilisé quelques fonctions et classes trouvées dans des sources précédentes avec quelques modifications notamment pour faire des balloon tooltips
(sur les contrôles et dans l'icône de la barre des tâches).
Ce programme utilise les classes Systray, ToolTip et ProgressBar.
Pour povoir reprendre les téléchargements j'ai dû utiliser les requêtes http (avec les headers nécessaires) ou les commandes spéciales ftp (notamment rest )
Des hotkeys permettent de démarrer le téléchargement même si le programme est réduit dans la barre des tâches (F3 copie le contenu du presse-papiers dans l'editbox et F2 démarre/interrompt le transfert).
Chaque seconde, l'état du transfert est mis à jour avec le nombre de Ko ou de Mo sur ce qu'il reste , ainsi que la vitesse du téléchargement instantanée en Ko/s et en Kbits/s.

Source / Exemple :


// un petit extrait de la thread de téléchargement

if (strcmp(uc.lpszScheme,"http")==0)
         {
               //Ouverture de la requête HTTP
               DistantFile=HttpOpenRequest(hProtoSession,"GET",uc.lpszUrlPath,NULL,NULL,NULL,INTERNET_FLAG_KEEP_CONNECTION, 0 );
               SetWindowText(GetDlgItem(Hwnd,ID_STATE),"Envoi de la requête...");
   
   
              //Prise en charge de la reprise          
               char RangeBytes[256];
               wsprintf(RangeBytes,"Range: bytes=%d-\r\n",sizelocal); // Exemple Ranges: bytes=0- obtient tout le fichier, Range: bytes=2564- démarre le téléchargement à partir de l'octet 2565 /!\ du fichier et jusqu'à la fin
               HttpAddRequestHeaders(DistantFile,RangeBytes,-1L,HTTP_ADDREQ_FLAG_ADD_IF_NEW);
               SetDlgItemText(Hwnd,ID_STATE,"Initialisation du téléchargement...");
    
              //Envoi réel de la requête
               HttpSendRequest(DistantFile,NULL,NULL,NULL,0);
               bool info=HttpQueryInfo(DistantFile,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,NULL,&sizehighdistant,0); //Détermination de la taille du fichier distant
               SetDlgItemText(Hwnd,ID_STATE,"Demande d'information sur le fichier...");
               info=HttpQueryInfo(DistantFile,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,&sizedistant,&sizehighdistant,0);
               if (!info) 
                  {
                       MessageBox(0,"Impossible d'obtenir des informations sur le fichier","Téléchargeur v2.0",MB_OK|MB_ICONSTOP);
                       ResetValues(Hwnd);
                       return 0;
                   }
               sizedistant+=sizelocal;
              }
    else if (strcmp(uc.lpszScheme,"ftp")==0)
            {
                       //Ouverture du fichier FTP
                        SetWindowText(GetDlgItem(Hwnd,ID_STATE),"Ouverture du fichier...");
                        DistantFile=FtpOpenFile(hProtoSession,uc.lpszUrlPath,GENERIC_READ,FTP_TRANSFER_TYPE_BINARY,INTERNET_FLAG_RELOAD);
                        
                        
                        //Prise en charge de la reprise
                        SetWindowText(GetDlgItem(Hwnd,ID_STATE),"Initialisation du téléchargement...");
                        sizedistant=FtpGetFileSize(DistantFile,&sizehighdistant);
                        InternetCloseHandle(DistantFile);
                        char Rest[256];
                        wsprintf(Rest,"REST %d",sizelocal);
                        bool commandrest=FtpCommand(hProtoSession,false,FTP_TRANSFER_TYPE_BINARY,Rest,NULL,NULL);
                        if (!commandrest) 
                              {
                                 MessageBox(Hwnd,"Erreur lors de l'envoi de la commande REST au serveur ftp!","Erreur",MB_OK|MB_ICONSTOP);
                                 ResetValues(Hwnd);
                                 return 0;
                              }
                        char Retr[256];
                        wsprintf(Retr,"RETR %s",uc.lpszUrlPath);
                        bool commandretr=FtpCommand(hProtoSession,true,FTP_TRANSFER_TYPE_BINARY,Retr,NULL,&DistantFile);
                        if (!commandretr)
                              {
                                 MessageBox(Hwnd,"Erreur lors de l'envoi de la commande RETR au serveur ftp!","Erreur",MB_OK|MB_ICONSTOP);
                                 ResetValues(Hwnd);
                                 return 0;
                              }
               }
            else  
                      {
                        
                        MessageBox(Hwnd,"Le type de transfert que vous demandez n'est pas pris en charge! Désolé!","Information",MB_ICONASTERISK);
                        ResetValues(Hwnd);
                        return 0;
                      }

// pour le reste cf zip

Conclusion :


J'aurais peut-être du poster la source quand le programme était moins compliqué mais je pense que l'utilisation des classes simpilfie la gestion du programme...
j'envisage de pouvoir gérer plusieurs téléchargements en même temps, et de pouvoir ainsi gérer tous les téléchargements qui n'ont pas été terminés.

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
13
Date d'inscription
mercredi 7 mai 2003
Statut
Membre
Dernière intervention
11 février 2005

je viens de tester mon programme avec un outil de débogage (WinDbg) et effectivement , lorsque qu'on télécharge un fichier de très petite taille ou bien qu'on essaye de reprendre un téléchargement déjà terminé, il y a aléatoirement une division par zéro (pas à chaque fois), je vais donc vérifier quelle(s) variable(s) sont en cause et je mettrai à jour.
Messages postés
13
Date d'inscription
mercredi 7 mai 2003
Statut
Membre
Dernière intervention
11 février 2005

pocky6> ah oui pourquoi pas faudrait que je revoie ça, vu que ça arrondit...

Kirua> oui euh en fait la vitesse calculée à partir de la dernière seconde écoulée (ou des dernières secondes si la boucle s'est effectuée en plus de 1 seconde notamment pour les débits inférieurs à 4Ko/s, vu que j'ai pris un tampon de 4 Ko)
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008

dis, juste parce que je suis un chicaneur, la vitesse que tu affiches, c'est pas la vitesse instantanée, c'est la vitesse moyenne (ponctuelle).
Messages postés
14
Date d'inscription
vendredi 31 janvier 2003
Statut
Membre
Dernière intervention
30 avril 2020

Je dis ça au pif mais... si ma mémoire est bonne quand on fait un ftp sur un petit fichier ça indique des vitesses de téléchargement folles... Est-ce qu'un tout petit temps de téléchargement serait pas considéré comme zéro, et donnerait une erreur de division par zéro dans le calcul de la vitesse ?
Messages postés
13
Date d'inscription
mercredi 7 mai 2003
Statut
Membre
Dernière intervention
11 février 2005

Merci beaucoup! je me suis beaucoup aidé de MSDN pour les balloon tooltips, les requêtes http, les commandes ftp...
Je suis dessus depuis septembre (j'ai pas trop le temps de programmer avec les études)
Par contre ça bugge pour les fichiers inférieurs à 2 Ko (ça télécharge bien le fichier mais à la fin le fameuse boîte de dialogie "ce programme a rencontré un problème et doit fermer..." apparaît), enfin c'est pas grave le but c'est de télécharger des gros fichiers :)
Afficher les 7 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.