[c++/ftp] Verbindungsabbruch


kickerxy123

Erfahrenes Mitglied
Hallo!
Ich habe ein Programm geschrieben, welches u.a. Dateien von einem ftp- Server herunterlädt und lokal speichert. Klappt auch relativ gut. Sprich: manchmal lädt er vollständig und richtig herunter, aber dann hin und wieder bricht er einfach mitten drin ab und es fehlen einige Mb (Die Datei ist bis zu dem Punkt allerdings ok, d.h. er überspringt keine Bytes o.ä. sondern arbeitet richtig und bricht dann einfach ab).
Jetzt ist die Frage, wie es zu diesen Verbindungsabbrüchen kommt. Es scheint übrigens nur bei größeren Dateien (>4MB) aufzutreten, aber, wie gesagt, nicht immer. Einmal hatte ich den Fall, dass er 4 mal die Datei heruntergeladen hat (4 mal unterschiedlich abgebrochen hat) und dann beim 5. mal alles richtig gelaufen ist.
Die Häufigkeit des Problemes ist hoch (alle 2-3 größere Dateien!).

hier ist meine (z.T. selbstgeschriebene) Download-Funktion:
Code:
int downloadFile(string pURL, int* pBytesRead)
{
    if(pURL == "") return -1;
    HINTERNET hInternet = InternetOpen("Microsoft Internet Explorer", INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
    
    if(!hInternet) return -2;
        const char* g;
    g = pURL.c_str();
    HINTERNET hURL = InternetOpenUrl(hInternet, g, 0, 0, INTERNET_FLAG_RELOAD, 0);
    
    if(!hURL)
    {
             CloseHandle(hInternet);
             CloseHandle(hURL);
             return -3;
    }

    CHAR*     buf; 
    string ergebnis = "";
    unsigned long long durchgang = 0;
        // Get inet file's size 
    DWORD dummy = 15;     
    CHAR      lpszFileSize[15]; 
    int       fileSize; 
    INT       step;
      
     FILE*     fFile; 
    HGLOBAL   hGlobal; 
    BOOL      bGO = TRUE; 
    DWORD     readSize = 256; 
    HttpQueryInfo(hURL, HTTP_QUERY_CONTENT_LENGTH, (LPVOID)lpszFileSize, &dummy, NULL); 
    fileSize = atoi(lpszFileSize); 
    if(fileSize == 0) 
    { 
       MessageBox(NULL, "The file you want to download doesn't exist\nor has file size zero", 
                  "Update-Error", MB_OK|MB_ICONERROR); 
       InternetCloseHandle(hURL); 
       InternetCloseHandle(hInternet); 
       return -4; 
    } 
    step = (fileSize / 100 == 0) ? 1 : fileSize / 100; 
 hGlobal = GlobalAlloc(GMEM_FIXED, step + 1); 
    buf = (CHAR*)GlobalLock(hGlobal); 
    
    
    string opendata = "";
    string ppURL = pURL;
    //Datei aus Pfad filtrieren
    for(int i = strlen(ppURL.c_str())-1;i>0;i--)
    {
            if(ppURL[i] == '/' || ppURL[i] == '\\') break;
            opendata+=ppURL[i];
}
//Richtigrum sortieren "invertieren"
string bufo = "";
for(int i = strlen(opendata.c_str())-1;i>=0;i--)
bufo += opendata[i];




string pfad = "xx\\";
pfad += bufo;
if(false == DirectoryExists( pfad ))
{_mkdir("xx");}
fFile = fopen(pfad.c_str(), "w+b"); 
if(!fFile)
{
ccout("Zugriff auf Speicherort oder Datei verweigert! Pfad: "+pfad);
writeToLog("Zugriff auf Speicherort oder Datei verweigert! Pfad: "+pfad,true,0);
return -6;
}

while(bGO) 
    { 
        bGO = InternetReadFile(hURL, buf, step, &readSize); 
        if(bGO && readSize == 0) 
           break; 
        buf[readSize] = '\0'; 
        fwrite(buf, 1, readSize, fFile); 
        downloadedBytes = downloadedBytes + step; 
        ergebnis += buf;
    } 

if(pBytesRead) *pBytesRead = downloadedBytes;
    InternetCloseHandle(hURL); 
    InternetCloseHandle(hInternet); 
    CloseHandle(hURL);
    CloseHandle(hInternet);
    fclose(fFile);
    downloadedBytes = 0;
    return fileSize; 

}

und wird in Threadfunktionen aufgerufen:
Code:
DWORD WINAPI DOWNLOAD_FILE(LPVOID data)
{
      
      string* ppara =  (string*)data;
      string para = *ppara;
      int parameter = (int)stringToInt(para);
      int downloadedBytes;
      int* pdownloadedBytes = &downloadedBytes;
do{
single_filesize =   downloadFile("http://gueltigeurl"+install_data[parameter], pdownloadedBytes);
if(single_filesize <= 0) 
{
writeToLog("Fehler: "+s_intToString(single_filesize)+" ...try again",false,0);
single_filesize = downloadedBytes + 1;  //Lade erneut (vgl do..while bedingung)
}
if(single_filesize > downloadedBytes)
{
writeToLog("unstimmige Größe, lade erneut!",false,0);

}}while(single_filesize > downloadedBytes);
return 0;
}

wie ich grade sehe.. handelt es sich wohl doch um einen http:// Zugriff :)
Ich hoffe ihr könnt mir weiterhelfen

ps: vielleicht auch noch interessant: manchmal gibt die Download-Funktion "-3" zurück (->URL konnte nicht gefunden werden), aber auch nur manchmal.. ich sehe da keine Systematik (Direkt nach dem Fehler "-3" geht es aber wieder, da meine while- Schleife bei diesem Fehler es ja erneut (erfolgreich) versucht).
ps2: je besser das Internet von jemanden ist, desto weniger Fehler tauchen bei demjenigen auf; ich: etliche( DSL 768) und Bekannter: keine (DSL 6000)

ps3: Kann mir vielleicht auch jemand sagen, wie ich (rechnerisch) von den downloaded_bytes auf die Filesize schließen kann?

ich habe zum Beispiel eine Datei heruntergeladen (Ftp Größe: 20.463.660 Bytes), wenns geklappt hat ist die lokale Größe natürlich ebensogroß.
Nur downloaded_bytes ist größer(hier: 20.668.236, Differenz von 204.576 Bytes). Er lädt also scheinbar noch weitere Bytes über die Verbindung o.ä.
Frage: was genau macht diese Variable größer und wie kann ich damit nun gucken, ob es mit der Filesize übereinstimmt (sollte schon Byte-genau sein!) Bisher gucke ich ja nur, ob er mehr gedownloaded hat, als die Datei groß ist, dies ist mir jedoch zu wage.

ps4: hm seltsam... bei einer anderen Datei ist die Größe überall gleich (auch die Downloaded Bytes!), vielleicht, weil diese Datei kleiner ist (852.500Bytes)


ich höre jetzt auf zu ps'en ;)

kickerxy
 
Zuletzt bearbeitet: