Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2935 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C/Reseau] Protocole FTP/ mode passif/ LIST&GET

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C/Reseau] Protocole FTP/ mode passif/ LIST&GET

n°2162577
hazaki
Posté le 05-11-2012 à 16:52:27  profilanswer
 

Bonjour,
Je dois réaliser un mini client FTP capable de contacter un serveur, lister les
 chiers proposes et telecharger l'un d'eux.
J'ai réussi à me connecter au serveur via une socket puis m'identifier en envoyant via la socket "USER anonymous" puis "PASS ..." et j'ai bien reçu le "230 Login succesful".
J'ai envoyé avec succés plusieurs commande comme HELP et PWD qui me renvoient des réponses censées mais quand j'essaye avec LIST, le serveur m'envoie "425 Failed to establish connection.".
Que dois-je faire ?
 
Merci pour vos réponses

mood
Publicité
Posté le 05-11-2012 à 16:52:27  profilanswer
 

n°2162579
Farian
Posté le 05-11-2012 à 17:24:26  profilanswer
 

Bonjour ! Comment gérez-vous la socket de data ?
 
Si vous êtes en mode passif, vous devez utiliser le couple adresse/port qui vous sera fourni par le serveur, en mode actif, c'est à vous de créer la socket serveur TCP et de laisser le serveur FTP s'y connecter.
 
Bon courage !

n°2162583
hazaki
Posté le 05-11-2012 à 18:06:52  profilanswer
 

Merci pour votre réponse,
 
J'ai eu un cours très rapide donc je ne suis pas sur de savoir tout faire.
J'ai donc une seule socket avec laquelle je me suis connecté au serveur avec le numéro de port fourni et je l'utilisais pour envoyer "USER anonymous"... et recevoir les messages venant du serveur.
Dois-je créer une autre socket ?

n°2162605
Farian
Posté le 05-11-2012 à 20:46:32  profilanswer
 

Oui ! Le protocole FTP est assez complexe, puisqu'il y a une socket dite "de commande", celle de la connexion, sur laquelle vous faites passer les commandes, les acquittements, les réponses, les synchros, .... et une socket dite "de données" sur laquelle les contenus de fichiers et les résultats de certaines commandes (comme LIST) sont envoyés.
 
C'est la gestion de cette socket que vous devez implémenter. Pour simplifier, et si vous travaillez en mode passif, le séquencement est le suivant (je ne fais pas figurer les messages "techniques" ) pour une commande LIST :  
 
 * Vous envoyez la commande "PASV",
 * Le serveur vous renvoie en réponse l'adresse et le port auxquels vous allez vous connecter pour créer la socket de données,
 * Une fois connecté, vous envoyez la commande "LIST" et le serveur écrit le résultat sur la socket de données précédemment créée.
  A la fin de la commande, la socket doit, de mémoire, être fermée.
 
Mais vous trouverez, sans aucun souci, de plus amples explications (ainsi que des diagrammes de séquence détaillés) sur Internet.
 
Bonne continuation !

n°2162613
hazaki
Posté le 05-11-2012 à 21:21:39  profilanswer
 

Ok, c'est bien ce que j'avais cru comprendre !
Merci beaucoup pour l'aide, j'essaye de programmer ça !

n°2162624
hazaki
Posté le 05-11-2012 à 23:22:25  profilanswer
 

C'est bon j'ai réussi, merci beaucoup pour ton aide !

n°2162630
Farian
Posté le 06-11-2012 à 06:01:53  profilanswer
 

De rien, quand on peut aider, c'est avec plaisir :)

n°2162814
hazaki
Posté le 06-11-2012 à 21:33:33  profilanswer
 

Hey, j'aurais encore besoin de votre aide car j'arrive à lister mais une seule fois !
Si j'établis la connexion puis ferme la socket à chaque listage, il n'arrive pas à se connecter la seconde fois, j'obtiens :  
Imposible de se connecter: Connection timed out
Aucune connexion possible
 
Et si je garde la connexion établie, à la deuxième tentative le serveur ne me répond rien !
 
Merci à vous de m'éclairer de votre sagesse !


Message édité par hazaki le 06-11-2012 à 22:03:56
n°2162824
Farian
Posté le 06-11-2012 à 22:33:13  profilanswer
 

Bonsoir !  
 
Le fait que cela marche lors de la première connexion est très encourageant ! :)  
 
De mémoire, la norme implique de recréer une socket à chaque commande, donc le deuxième fonctionnement que vous décrivez paraît correct.  
 
Êtes-vous en mode passif ou actif ? Si vous êtes en mode actif, changez-vous de port d'une fois sur l'autre ? Si vous gardez le même, utilisez-vous l'option SO_REUSEADDR ? Si cela ne vient pas de là, vérifiez qu'il ne manque rien ou postez-nous la partie concernée de votre programme.
 
Je ne peux guère vous en dire plus en l'état :)

n°2162847
hazaki
Posté le 06-11-2012 à 23:07:08  profilanswer
 

Merci pour la réponse,
Donc je suis en mode passif, et malgré mes recherches je n'ai pas trouver la norme à utiliser.
J'ai cru trouver que pour passif il faut à chaque fois réétablir la connexion donc voilà ce que j'ai fait :
 
else if(strcmp(commande,"lister" )==0)
{    
        socket2=connexion(port2,serveur2);
        envoieMessage(socket,"LIST\r\n" );
        nblus=recv(socket2,buf,TAILLE_BUFF,0);
        if(nblus==0)
        {
                 printf("Erreur de reception de message\n" );
        }
        buf[nblus]='\0';
        printf(" %s", buf);
        close(socket2);
        }
}


Message édité par hazaki le 06-11-2012 à 23:25:17
mood
Publicité
Posté le 06-11-2012 à 23:07:08  profilanswer
 

n°2162856
Farian
Posté le 06-11-2012 à 23:35:19  profilanswer
 

En mode passif, il vous suffit avant chaque commande LIST/RETR/STOR d'envoyer une commande PASV, normalement, mais c'est a priori ce que vous avez du faire pour la première connexion ...
 

n°2162858
Farian
Posté le 06-11-2012 à 23:37:43  profilanswer
 

Après avoir lu votre message, je me dis que vous ne renvoyez peut-être pas systématiquement une commande PASV ...
 
Voici par exemple un log rapide d'une session en passif :  
 

(000003)06/11/2012 23:36:54 - (not logged in) (127.0.0.1)> Connected, sending welcome message...  
(000003)06/11/2012 23:36:54 - (not logged in) (127.0.0.1)> 220-FileZilla Server version 0.9.41 beta
(000003)06/11/2012 23:36:54 - (not logged in) (127.0.0.1)> 220-written by Tim Kosse (Tim.Kosse@gmx.de)
(000003)06/11/2012 23:36:54 - (not logged in) (127.0.0.1)> 220 Please visit http://sourceforge.net/projects/filezilla/
(000003)06/11/2012 23:36:54 - (not logged in) (127.0.0.1)> USER oo
(000003)06/11/2012 23:36:54 - (not logged in) (127.0.0.1)> 331 Password required for oo
(000003)06/11/2012 23:36:54 - (not logged in) (127.0.0.1)> PASS *
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> 230 Logged on
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> SYST
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> 215 UNIX emulated by FileZilla
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> FEAT
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> 211-Features:
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)>  MDTM
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)>  REST STREAM
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)>  SIZE
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)>  MLST type*;size*;modify*;
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)>  MLSD
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)>  UTF8
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)>  CLNT
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)>  MFMT
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> 211 End
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> PWD
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> 257 "/" is current directory.
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> TYPE I
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> 200 Type set to I
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> PASV
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> 227 Entering Passive Mode (127,0,0,1,4,0)
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> LIST
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> 150 Connection accepted
(000003)06/11/2012 23:36:54 - oo (127.0.0.1)> 226 Transfer OK
(000003)06/11/2012 23:37:17 - oo (127.0.0.1)> CWD /cygwin
(000003)06/11/2012 23:37:17 - oo (127.0.0.1)> 250 CWD successful. "/cygwin" is current directory.
(000003)06/11/2012 23:37:17 - oo (127.0.0.1)> PWD
(000003)06/11/2012 23:37:17 - oo (127.0.0.1)> 257 "/cygwin" is current directory.
(000003)06/11/2012 23:37:17 - oo (127.0.0.1)> PASV
(000003)06/11/2012 23:37:17 - oo (127.0.0.1)> 227 Entering Passive Mode (127,0,0,1,4,1)
(000003)06/11/2012 23:37:17 - oo (127.0.0.1)> LIST
(000003)06/11/2012 23:37:17 - oo (127.0.0.1)> 150 Connection accepted
(000003)06/11/2012 23:37:17 - oo (127.0.0.1)> 226 Transfer OK


Message édité par Farian le 06-11-2012 à 23:52:23
n°2162862
hazaki
Posté le 06-11-2012 à 23:54:38  profilanswer
 

Ah ok !
Merci beaucoup pour la réponse !
Donc j'ai fait comme vous m'avez dit mais pour la deuxième tentative de listage je reçois :
150 Here comes the directory listing.
226 Directory send OK.
au lieu du bon vieux 227

n°2162864
Farian
Posté le 07-11-2012 à 00:00:12  profilanswer
 

Le code 226 correspond à la fin de l'envoi par le serveur, donc au moment où vous pouvez normalement fermer la socket de données (et au moment où lui même ferme la socket en mode actif).
 
Le 227 est la réponse au PASV ...  
 
Pouvez-vous poster une version à jour de votre code ?
 
Edit : Et si possible un log FileZilla Server de la session :)


Message édité par Farian le 07-11-2012 à 00:01:07
n°2162867
hazaki
Posté le 07-11-2012 à 00:06:34  profilanswer
 

Voici le code
C'est le print associé au PASV qui beugue lors de la deuxième tentative !
 

Code :
  1. else if(strcmp(commande,"lister" )==0)
  2.  {
  3.   if(nbParam==1)
  4.   {
  5.    printf("il y a un parametre en trop" );
  6.   }
  7.   else
  8.   {
  9.    envoieMessage(socket,"PASV\r\n" );
  10.    nblus=recv(socket,buf,TAILLE_BUFF,0);
  11.    if(nblus==0)
  12.    {
  13.     printf("Erreur de reception de message" );
  14.     return -1;
  15.    }
  16.    buf[nblus]='\0';
  17.    printf("%s", buf);
  18.    trouverAdresse2(buf,nblus,serveur2,port2);
  19.    socket2=connexion(port2,serveur2);
  20.    envoieMessage(socket,"LIST\r\n" );
  21.    nblus=recv(socket2,buf,TAILLE_BUFF,0);
  22.    if(nblus==0)
  23.    {
  24.     printf("Erreur de reception de message\n" );
  25.    }
  26.    buf[nblus]='\0';
  27.    printf(" %s", buf);
  28.    close(socket2);
  29.   }


  }

n°2162868
Farian
Posté le 07-11-2012 à 00:15:23  profilanswer
 

Ce qui me chagrine en lisant votre code est que vous ne vous synchronisez pas du tout sur les réponses du serveur, et que vous ne lisez pas la réponse après chaque envoi de commande, ce qui rend l'analyse plus difficile.
 
D'après ce que j'ai compris, vous devriez attendre le code de retour 150 après l'envoi de LIST pour vous connecter à la socket de données, mais cela marche peut-être aussi dans ce sens-là.
 
Je pense que vous n'échapperez pas au fait de lire la réponse à chaque commande envoyée, et à la comparaison du code de retour avec ce que vous attendez ...
 
Enfin, la nuit portant conseil, peut-être aurons-nous les idées plus claires après une bonne nuit de sommeil :)

n°2162869
hazaki
Posté le 07-11-2012 à 00:19:30  profilanswer
 

Ok j'écoute la socket de commande et j'ai bien reçu le 150 du premier lister mais le problème n'est pas résolu pour autant
Bonne nuit ;)


Message édité par hazaki le 07-11-2012 à 00:57:38
n°2162872
Farian
Posté le 07-11-2012 à 05:58:49  profilanswer
 

Bon, après une bonne nuit, les choses se mettent en place !
 
Concernant la commande LIST, vous devez attendre le retour 150 pour vous connecter à la socket de données, lire sur cette socket le contenu du répertoire, puis attendre de recevoir le retour 226 pour vous déconnecter et que le cycle d'échanges pour cette commande soit terminé.
 
Si vous ne lisez pas ce code de retour, quand vous enverrez la commande PASV, en lisant le contenu de la socket de commande vous y trouverez le message 226 qui n'a pas été dépilé du coup d'avant.
 
Logiquement, nous ne devrions pas être très loin de la gagne, là !

n°2162885
hazaki
Posté le 07-11-2012 à 09:29:04  profilanswer
 

Ok, et bien cela fonctionne parfaitement maintenant !
Merci encore pour votre aide !

n°2162926
Farian
Posté le 07-11-2012 à 10:52:16  profilanswer
 

:bounce:  :bounce:  :bounce:  


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C/Reseau] Protocole FTP/ mode passif/ LIST&GET

 

Sujets relatifs
ULR rewriting Multi-Getprogramme C :jeu de cartes
Programme C++ , erreur ? Ou ça ?[C] Conversion type énuméré en string pour affichage :
programme C[C#] dataset ajouter une ligne depuis textbox
[C/Ada] Traduction de C avec Ada de la bibliothèque portmidi.Compilation fichier C et H
[RESOLU] socket inter-process C/PHP linuxPetit problème - langage C
Plus de sujets relatifs à : [C/Reseau] Protocole FTP/ mode passif/ LIST&GET


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR