Protocole FTP/ mode passif/ LIST&GET [C/Reseau] - C - Programmation
Marsh Posté le 05-11-2012 à 17:24:26
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 !
Marsh Posté le 05-11-2012 à 18:06:52
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 ?
Marsh Posté le 05-11-2012 à 20:46:32
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 !
Marsh Posté le 05-11-2012 à 21:21:39
Ok, c'est bien ce que j'avais cru comprendre !
Merci beaucoup pour l'aide, j'essaye de programmer ça !
Marsh Posté le 06-11-2012 à 21:33:33
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 !
Marsh Posté le 06-11-2012 à 22:33:13
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
Marsh Posté le 06-11-2012 à 23:07:08
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);
}
}
Marsh Posté le 06-11-2012 à 23:35:19
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 ...
Marsh Posté le 06-11-2012 à 23:37:43
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... |
Marsh Posté le 06-11-2012 à 23:54:38
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
Marsh Posté le 07-11-2012 à 00:00:12
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
Marsh Posté le 07-11-2012 à 00:06:34
Voici le code
C'est le print associé au PASV qui beugue lors de la deuxième tentative !
Code :
|
}
Marsh Posté le 07-11-2012 à 00:15:23
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
Marsh Posté le 07-11-2012 à 00:19:30
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
Marsh Posté le 07-11-2012 à 05:58:49
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à !
Marsh Posté le 07-11-2012 à 09:29:04
Ok, et bien cela fonctionne parfaitement maintenant !
Merci encore pour votre aide !
Marsh Posté le 05-11-2012 à 16:52:27
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