[C++ | FTP ] Probleme WinInet API pour client FTP

K-lo
[C++ | FTP ] Probleme WinInet API pour client FTP

Voilà j'ai un client FTP qui doit recupérer tous les fichiers ayant le même nom que le fichier ayant une extension ".exe"

Voici mon code (simplifié) :

//connexion :
hInternetSession = InternetOpen(L"Client FPT", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL,0);
hFtpSession = InternetConnect(hInternetSession, hote, (INTERNET_PORT)port, user, pass, INTERNET_SERVICE_FTP, 0, 0);


//liste des fichiers ayant pour nom le fichier de reference.exe
HINTERNET h_lstFTP = NULL;
std::wstring commandeList = L"NLST "+ nomDuRepertoirAParcourir + fichierDeReference+L"*";
FtpCommand(hFtpSession, TRUE, FTP_TRANSFERT_TYPE_BINARY, commandeList.c_str(), 0, &lstFTP );
char ret [4096];
DWORD dwBytesread;
if(InternetReadFile(h_lstFTP,ret, 4095,&dwBytesread){
	std::wcerr<<L"Erreur InternetReadFile\n";
}else{
	ret[dwBytesread]=0;
}
std::wstring str1 = convertionConstCharToWChar(ret); 
std::wstring strSortie;
for (std::wstring::iterator it = str1.begin(); itStr != str1.end(); ++itStr)
{
	if( *itStr != 0x0D ){
		strSortie.push_back(*itStr);	
	}
}
boost::algorithm::split(ListNomDeFichier, strSortie, boost::algorithm::is_any_of(L"\x0A"));
InternetCloseHandle(h_lstFTP);

for( std::list<std::wstring>::iterator itLFich = ListNomDeFichier.begin(); itLFich != ListNomDeFichier.end(); ++itLFich ){
	
	//...
	HINTERNET hFile;
//recuperation de la taille
        hFile = FtpOpenFile(hFTPSession, cheminVersFichierATelecahrger, GENERIC_READ, FTP_TRANSFERT_BINARY,NULL);
        if(FtpGetSize(hFile) == 0 ){
           std::cout<<"fichier de taille 0";
        }
        InternetCloseHandle(hFile);
	if(!FtpGetFIle(hFTPSession, cheminVersFichierATelecahrger, cheminDuFichierEnLocal, NULL, FILE_ATTRIBUTE_NORMAL,0,NULL)){
		std::wcerr<<"Erreur "<<GetLastError()<<"\n";
		//...
	}	

      
        //...	
}

Le souci c'est que le serveur FTP sur lequel je me connecte est sous Linux et je dois déployer le client sur une machine (pas très ressente) en Windows (windows 2000 avec la sp4). Et j'ai lors du téléchargement du fichier l'erreur 12003 ! Par conséquent lorsque j'affiche la raison de cette erreur via la fonction : InternetGetLastResponseInfo();
Il me répond : "150 opening binary mode data connction for "nomdufichier.exe"
Ce qui est un comportement "normale".
Dans la MSDN on m'informe que l'erreur vient du faite que les 2 machines ne se comprennent pas bien et qu'il faut utiliser l'indicateur INTERNET_FLAG_PASSIVE comme flag pour la fonction InternetConnect().
Sauf que ça ne fonctionne pas il me renvoi l'erreur 12029...

J'ai pas ce problème avec des machines ressentes sous windows 2000.
Ce qui m'incite à venir exposer mon problème aux personnes expérimentés :P

Merci

K-lo

HINTERNET hFile;
//recuperation de la taille
        hFile = FtpOpenFile(hFTPSession, cheminVersFichierATelecahrger, GENERIC_READ, FTP_TRANSFERT_BINARY,NULL);
        if(FtpGetSize(hFile) == 0 ){
           std::cout<<"fichier de taille 0";
        }
        InternetCloseHandle(hFile); 

en supprimant la partie de code ci-dessus (récupération de la taille du fichier) je n'ai plus aucun souci...
Mais je comprends pas trop pourquoi sur les postes ressent avec win2000 et sp4 ça fonction avec la récupération de la taille et pas sur les postes en win2000 et sp4... Comem si sur les ancien poste le InternetCloseHandle(hFile); ne travail pas correctement...
K-lo

Je sais que mon problème est un peu tiré par les cheveux donc si personne ne peux me répondre ça me posera pas de souci : :lol:

fredericmazue

Quote:
avec win2000 et sp4 ça fonction avec la récupération de la taille et pas sur les postes en win2000 et sp4...

Ah ouais :?: :lol: :lol:
Quote:
n supprimant la partie de code ci-dessus (récupération de la taille du fichier) je n'ai plus aucun souci...

Je ne comprends pas tout bien...
Tu ne le fermais pas prématurément ton fichier avec "le bout de code" ?
fredericmazue

Salut k-lo

Je reviens sur ta question:

- ça ne me regarde pas, mais je me suis demandé: std::wstring str1 = convertionConstCharToWChar(ret); pourqoi diable convertit-il en WCHAR là ?

- d'ou tu sors ça:

if(FtpGetSize(hFile) == 0 ){ 
           std::cout<<"fichier de taille 0"; 
        } 

Moi je ne connais pas de fonction FtpGetSize prenant un seul argument.
Je connais FtpGetFileSize qui prend d'ailleurs deux arguments. D'ou diable sors tu FtpGetSize. C'est une fonction à toi de derrière les fagots ?

Bon regardons ton affaire de plus près. Je pars du principe que ce FtpGetSize appelle FtpGetFileSize. Là tu fais une opération réseau. Donc tu es dans un contexte asynchrone.
Regarde bien ce que dis la doc de InternetCloseHandle:

Quote:
If asynchronous requests are pending for the handle or any of its child handles, the handle cannot be closed immediately, but it will be invalidated. etc etc

Bref ce qui se passe apparement c'est que quand tu regardes la taille du fichier, le protcole Ftp n'a pas encore fini de travailler que toi tu cherches à fermer le Handle et ça fout la m.... Comme dit dans la MSDN tu devrais tester avec getLastError s'il y a une opération "pendante" avant de fermer. (bienvenue et bon courage dans le domaine de la programmation des E/S asynchrone sous Windows :twisted: :lol:)

Maintenant pourquoi ça marche sur un Windws et pas sur un autre Parce que dans l'un il s'arrange pour ne pas laisser une opération pendante, et pas dans l'autre. mais c'est de ta faute dans les deux cas. Tu devrais tester systématiquement s'il y a une E/S pendante avant d'appeler InternetCloseHandle, parce que c'est ce qui se déduit des "Remarks" de la MSDN, Remarks qu'il faut toujours, comme tu le sais, lire entièrement et extrêmement attentivement :(

Oui oui ça alourdit énormément la programmation de faire ce test :(

K-lo

Quote:
Moi je ne connais pas de fonction FtpGetSize prenant un seul argument.
Je connais FtpGetFileSize qui prend d'ailleurs deux arguments. D'ou diable sors tu FtpGetSize. C'est une fonction à toi de derrière les fagots ?

Je me suis trompé en recopiant (je réécrit tout le code à la main/clavier sur le forum et effectivement c'est celle que tu connais avec 2 arguments) :oops:

Quote:
- ça ne me regarde pas, mais je me suis demandé: std::wstring str1 = convertionConstCharToWChar(ret); pourqoi diable convertit-il en WCHAR là ?

Ca c'est une tirée de derrière les fagots et j'aime pas faut que je vérifie pourquoi l'avoir garder à ce niveau / je crois que : je voulais tous gérer en wstring et que je me suis retrouvé confronté ne pas pouvoir utiliser ce type de donner directement... pour InternetReadFile()... Humm vais vérifé le tout car c'est suspect.


Quote:
bienvenue et bon courage dans le domaine de la programmation des E/S asynchrone sous Windows
Maintenant pourquoi ça marche sur un Windws et pas sur un autre Parce que dans l'un il s'arrange pour ne pas laisser une opération pendante, et pas dans l'autre. mais c'est de ta faute dans les deux cas.

Oui et comme je me disais : "Non mais FtpGetFile ne prends pas un handler mais un nom de fichier je me suis dit à tord bah ça doit pas gêner => Et là j'ai oublier une base de la programmation sur flux on fait pas 2 choses en même tps sur un flux n'importe comment...

Reste à gérer le truc comme il faut....

fredericmazue

Quote:
(je réécrit tout le code à la main/clavier sur le forum

Heu.. le copier/coller marche très bien sur le forum...