2013-01-21 3 views
1

Je suis un petit nouveau sur le site ici, alors pardonnez-moi si je fais quelque chose de mal dans ce poste.InternetReadFile() ne semble pas lire les données sur Internet

Je travaille avec WinINet et essayer de télécharger un binary file de l'Internet mais, pour une raison quelconque quand je reçois au point de télécharger ce fichier en utilisant en fait InternetReadFile(), il ne renvoie rien lire du tout (0 octets d'information lire). Exécution de l'Visual Studio 2012 debugger a révélé que les détails pour moi, parce que le gestionnaire HINTERNET que j'alimentation dans l'appel d'API a certainement des données pour sûr. Je ne comprends tout simplement pas ce que je fais de mal. Peut-être que vous pouvez aider les gars?

L'essentiel de base de mon programme est que je télécharge un fichier binaire sur le net, et l'enregistrer dans un fichier temporaire qui se trouve dans un répertoire temporaire. Après avoir copié le contenu dans le fichier temporaire, je transfère le contenu des données binaires de ce fichier temporaire dans un autre fichier local (cette fois dans un répertoire valide). Voici ce que j'ai jusqu'ici. Si tout va bien avec la répartition logique que je fournis, les gars seront en mesure de le suivre malgré la longueur du code ...

#include "httpfileretrieval.h" // contains all handlers (hInstance, etc.) 

bool downloadFile(const char* lpszServer, const char* lpszUrl, const char* destPath) 
{ 
    FILE *tempFile = NULL; 
    FILE *localFile = NULL; 

    const int bufsize = 4096; 
    DWORD tempDirBytes; 
    DWORD dwSize = 4096;   // experiment - ignore the fact this is the same as bufsize 
    DWORD dwRead = 0; 

    char lpszDataBuffer[bufsize]; 
    lpszDataBuffer[bufsize] = '\0'; 

    char tempPath[MAX_PATH]; 
    char tempFileName[bufsize]; // will hold the FULL temp file path 

    std::string srcPath; 
    srcPath.append(lpszServer); 
    srcPath.append(lpszUrl); // http://www.domain.com/url into srcPath 

    hInstance = InternetOpen("httpfret", 
         INTERNET_OPEN_TYPE_PRECONFIG, 
         NULL, 
         NULL, 
         INTERNET_FLAG_ASYNC); // ASYNC Flag 

    if (!hInstance) 
    { 
     DWORD errorNum = GetLastError(); 
     fprintf(stderr, "InternetOpen Failed! Windows Error %d\n", errorNum); 
     return false; 
    } 

    // Setup callback function due to INTERNET_FLAG_ASYNC 
    if (InternetSetStatusCallback(hInstance,(INTERNET_STATUS_CALLBACK)&Callback) 
    == INTERNET_INVALID_STATUS_CALLBACK) 
    { 
     DWORD errorNum = GetLastError(); 
     fprintf(stderr, "InternetSetStatusCallback Failed! Windows Error %d\n", errorNum); 
     return false; 
    } 

    // First call that will actually complete asynchronously even though 
    // there is no network traffic 
    hConnect = InternetConnect(hInstance, 
          lpszServer, 
          INTERNET_DEFAULT_HTTP_PORT, 
          NULL, 
          NULL,hg 
          INTERNET_SERVICE_HTTP, 
          0, 
          1); // Connection handle's Context 
    if (!hConnect) 
    { 
     if (GetLastError() != ERROR_IO_PENDING) 
     { 
      DWORD errorNum = GetLastError(); 
      fprintf(stderr, "InternetConnect Failed! Windows Error %d\n", errorNum); 
      InternetCloseHandle(hInstance); 
      return false; 
     } 
     // Wait until we get the connection handle 
     WaitForSingleObject(hConnectedEvent, INFINITE); 
    } 


    // Open the request 
    hRequest = HttpOpenRequest(hConnect, "GET", lpszUrl, NULL, NULL, NULL, 
          INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, 
          2); // Request handle's context 
    if (!hRequest) 
    { 
     if (GetLastError() != ERROR_IO_PENDING) 
     { 
      DWORD errorNum = GetLastError(); 
      fprintf(stderr, "HttpOpenRequest Failed! Windows Error %d\n", errorNum); 
      InternetCloseHandle(hConnect); 
      InternetCloseHandle(hInstance);h 
      return false; 
     } 
     // Wait until we get the request handle 
     WaitForSingleObject(hRequestOpenedEvent, INFINITE); 
    } 

    // Send the request 
    if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)) 
    { 
     if (GetLastError() != ERROR_IO_PENDING) 
     { 
      DWORD errorNum = GetLastError(); 
      fprintf(stderr, "HttpSendRequest Failed! Windows Error %d\n", errorNum); 
      InternetCloseHandle(hRequest); 
      InternetCloseHandle(hConnect); 
      InternetCloseHandle(hInstance); 
      return false; 
     } 
    } 

    if (bVerbose) 
    { 
     printf("HttpSendRequest called successfully\n"); 
    } 

    WaitForSingleObject(hRequestCompleteEvent, INFINITE); 

    // Before downloading file... 
    // 1. Get the temp directory 
    if (!(tempDirBytes = GetTempPathA(MAX_PATH, tempPath))) 
    { 
     fprintf(stderr, "Could not get temporary directory\n"); 
     InternetCloseHandle(hRequest); 
     InternetCloseHandle(hConnect); 
     InternetCloseHandle(hInstance); 
     return false; 
    } 

    // 2. Get temp file name (full name: tempPath\temp.tmp) 
    srand(GetTickCount()); 
    sprintf(tempFileName, "%s\\%08X.tmp", tempPath, rand()); 

    // Error check the end of temp file name for ending double slash 
    if (tempFileName[bufsize] == '\\') 
     tempFileName[bufsize] = '\0'; 

    // 3. Create temp file 
    printf("Creating temp file %s\nto store %s\n", tempFileName, srcPath.c_str()); 
    tempFile = fopen(tempFileName, "wb");  // Open the file for writing 
    if (!tempFile) 
    { 
     DWORD errorNum = GetLastError(); 
     fprintf(stderr, "Could not create temp file! Error %d\n", errorNum); 
     InternetCloseHandle(hRequest); 
     InternetCloseHandle(hConnect); 
     InternetCloseHandle(hInstance); 
     return false; 
    } 
    printf("Done!\n\n"); 

    printf("------------------- Read the response -------------------\n"); 

    unsigned long n = 0; 
    unsigned long sum = 0; 

    printf("Copying %s\n to %s\n", srcPath.c_str(), tempFileName); 


    // WHERE THE MAGIC HAPPENS - AND WHERE EVERYTHING FAILS! 
    while (InternetReadFile(hRequest, lpszDataBuffer, dwSize, &dwRead) && !(bAllDone)) 
    { 
     if (dwRead != 0) 
     { 
      sum = 0; 
      fwrite(lpszDataBuffer, 1, dwRead, tempFile); 
      for (unsigned long i = 0; i < dwRead; ++i) 
      { 
       sum += lpszDataBuffer[i]; 
       sum %= 0xFFFF; 
      } 
      printf("Received 4KB block %d. Sum %04X\r", n++, sum); 
     } 
     else 
     { 
      bAllDone = TRUE; 
      printf("\n"); 
      break; 
     } 
    } 

    printf("\n\n------------------- Request Complete ----------------\n"); 



    fclose(tempFile);    // Done writing to file 
    tempFile = fopen(tempFileName, "rb"); // Reopen for reading 


    //Create the local file 
    printf("Creating local file %s\n", destPath); 
    localFile = fopen(destPath, "wb"); 
    if (!localFile) 
    { 
     DWORD errorNum = GetLastError(); 
     fprintf(stderr, "Could not create local file! Windows Error %d\n", errorNum); 
     fclose(tempFile); 
     remove(tempFileName);  // delete temporary file from machine 
     InternetCloseHandle(hRequest); 
     InternetCloseHandle(hConnect); 
     InternetCloseHandle(hInstance); 
     return false; 
    } 
    printf("Done!\n\n"); 


    // Copy the contents from the temp file to the local file 
    printf("Copying temp file %s contents\nto local file %s\n", tempFileName, destPath); 
    if (!copyFile(tempFile, localFile)) 
    { 
     DWORD errorNum = GetLastError(); 
     fprintf(stderr, "Could not copy temp file to local directory! Windows Error\n", errorNum); 
     fclose(tempFile); 
     remove(tempFileName);  // delete temporary file from machine 
     fclose(localFile); 
     InternetCloseHandle(hRequest); 
     InternetCloseHandle(hConnect); 
     InternetCloseHandle(hInstance); 
     return false; 
    } 
    printf("Done!\n\n"); 






    // end of logic housekeeping 
    fclose(tempFile); 

    printf("Deleting temp file %s\n", tempFileName); 
    remove(tempFileName); // delete temporary file from machine 
    printf("Done!\n\n"); 

    fclose(localFile); 

    printf("Ending Internet Session\n"); 
    InternetCloseHandle(hRequest); 
    InternetCloseHandle(hConnect); 
    InternetCloseHandle(hInstance); 
    printf("Done!\n"); 

    printf("Press Enter to continue\n"); 
    std::cin.get(); 


    return true; 
} 
+0

Pouvez-vous s'il vous plaît charger le code complet afin qu'il puisse être jugé par d'autres? Il y a quelques fichiers manquants tels que httpfileretrieval.h. Si le code est prêt à être construit, il sera plus utile pour les autres développeurs de comprendre et de faire leurs commentaires et suggestions. Merci. –

+0

arriv moi aussi: au coût de regarder muet, je partage la raison pour laquelle il ne fonctionne pas pour moi. Cela ne marchera pas si vous l'appelez après avoir déjà reçu toutes les données. – reallynice

Répondre

2

Votre code fonctionne pour moi. Êtes-vous sûr que le serveur renvoie une réponse non vide? Vous pouvez utiliser un outil comme Fiddler2 pour vérifier. Il y a quelques problèmes dans ce code, y compris un débordement de tampon ici: lpszDataBuffer[bufsize] = '\0';. En outre, vous utilisez le mode asynchrone, mais vous n'avez aucune gestion asynchrone dans votre boucle de lecture. Je recommande que vous postez le code pour examen ici: https://codereview.stackexchange.com/.

Une note finale. Si vous attendez que chaque opération soit terminée, il n'y a aucun avantage à faire les choses de manière asynchrone. Vous pouvez laisser le drapeau INTERNET_FLAG_ASYNC. Cela rendra votre fonction beaucoup plus simple.

+0

Merci d'avoir répondu à Peter. Oui, vous aviez raison sur le drapeau 'INTERNET_FLAG_ASYNC'. Je l'avais à l'origine pour fournir une sortie interactive sur la console pour que l'utilisateur puisse voir ce qui se passait en arrière-plan, mais j'ai décidé d'avoir juste une sortie séquentielle selon la logique du programme. Au moment où j'ai enlevé ce drapeau, tout a fonctionné comme un charme. Merci de votre aide! – Danchez

Questions connexes