S
Also ich habe es jetzt den Download vom FTP mit den Funktionen FtpOpenFile() und InternetReadFile() realisiert. Das funktioniert!!!
InternetReadFile() befindet sich natürlich in einer Schleife. Wenn auf den Close-Button gedrückt wird, wird die Schleife verlassen und danach InternetCloseHandle() aufgerufen für die drei Handles, die während des Vorgangs erzeugt werden (müssen). Erst wenn das alles erledigt ist, wird PostQuitMessage(0) aufgerufen.
So kann ich den Download munter 20-30 mal aufrufen (wahrscheinlich auch öfter, aber ich hatte kein bock noch weiter zu testen) und der FTP-Server nimmt weiterhin neue Vebindungen an. Sieht im Prinzip so aus (was wäre ein Thread ohne Code...?!):
//Globale Variable:
bool globalVar_downloadStoppen; //mit 'false' initialisiert
bool globalVar_downloadBeendet; //mit 'false' initialisiert
CRITICAL_SECTION globalVar_critSec;
//------------------------------------------------------------------------------
HINTERNET hiOpen = InternetOpenA("Meine_Anwendung",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);
if(!hiOpen){MessageBoxA(NULL,"InternetOpen fehlgeschlagen","",MB_OK);}
HINTERNET hiConnect = InternetConnectA(hiOpen,"server.abc",INTERNET_DEFAULT_FTP_PORT,"benutzername","passwort",INTERNET_SERVICE_FTP,INTERNET_FLAG_PASSIVE,kontext);
if(!hiConnect){MessageBoxA(NULL,"InternetConnect fehlgeschlagen","",MB_OK);}
HINTERNET hiFile = FtpOpenFileA(hiConnect,"Datei.dat",GENERIC_READ,FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD,kontext);
if(!hiFile){MessageBoxA(NULL,"FtpOpenFile fehlgeschlagen","",MB_OK);}
char puffer[1024];
DWORD dateiGröße = 12345;
DWORD gelesenAktuell;
DWORD gelesenDatei = 0;
FILE* lokaleDatei = fopen("C:\\Datei.dat","wb");
bool lokalVar_downloadStoppen = false;
while(gelesenDatei < dateiGröße && !lokalVar_downloadStoppen)
{
InternetReadFile(hiFile,puffer,min(1024,dateiGröße-gelesenDatei),&gelesenAktuell);
gelesenDatei += gelesenAktuell;
fwrite(puffer,sizeof(char),gelesenAktuell,lokaleDatei);
zeichneLadeBalken(gelesenDatei,dateiGröße);
EnterCriticalSection(&globalVar_critSec);
lokalVar_downloadStoppen = globalVar_downloadStoppen;
LeaveCriticalSection(&globalVar_critSec);
}
fclose(lokaleDatei);
InternetCloseHandle(hiFile);
InternetCloseHandle(hiConnect);
InternetCloseHandle(hiOpen);
EnterCriticalSection(&globalVar_critSec);
globalVar_downloadBeendet = true;
LeaveCriticalSection(&globalVar_critSec);
//Vor PostQuitMessage(0) wird gewartet bis globalVar_downloadBeendet a8f 'true' gesetzt wurde
UrlDownloadToFile() beendet die Verbindung zum FTP-Server nicht korrekt . So sieht es für mich jedenfalls aus... Ich benutze prinzipiell den selben Shutdown-Mechanismus: Klick auf den Close-Button -> UrlDownloadToFile() verlassen -> dann erst PostQuitMessage(0). UrlDownloadToFile() wird verlassen indem in der OnProgress()-Methode E_ABORT zurückgegeben wird anstatt S_OK.
Aber da kann ich ich meine Anwendung nur fünf mal starten und beenden. Beim sechsten mal kann keine Verbindung mehr zum FTP-Server aufgebaut werden. Der Server meldet "421 Too many connections (5) from this IP".
Also Vorteil der jetzigen Variante ist, dass ich keine Probleme mehr hab mit dem Neustart meiner Anwendung und den Downloads.
Nachteil: Ich bin mit meiner URL an das FTP-Protokoll gebunden. Ich muss eine Entscheidung implementieren, ob es FTP oder HTTP sein soll.
Bei UrlDownloadToFile() konnte ich einfach irgendeine URL übergeben.
MfG