CFTPSERVER, CLASSE C++ D'UN SERVEUR FTP COMPLET ET RAPIDE. WIN32 ET LINUX

Taron31 Messages postés 199 Date d'inscription vendredi 16 avril 2004 Statut Membre Dernière intervention 28 février 2008 - 11 nov. 2005 à 15:10
ufukendu59 Messages postés 7 Date d'inscription samedi 23 mai 2009 Statut Membre Dernière intervention 20 juillet 2010 - 19 juil. 2010 à 03:28
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/34583-cftpserver-classe-c-d-un-serveur-ftp-complet-et-rapide-win32-et-linux

ufukendu59 Messages postés 7 Date d'inscription samedi 23 mai 2009 Statut Membre Dernière intervention 20 juillet 2010
19 juil. 2010 à 03:28
Salut !

Ton code à l'air d'être sympa mais tu pourrai m'expliquer comment sa marche concrètement parce que moi je suis un gros zéros pour ce qui est du réseau ,ce serait hyper gentil.

Et une question ,je suis sous code blocks ,sa marche aussi ?

Merci d'avance !!

Cordialement,

ufukendu59
cs_abdenour123 Messages postés 17 Date d'inscription lundi 21 janvier 2008 Statut Membre Dernière intervention 29 mai 2009
8 sept. 2008 à 22:47
voici les code errur avec console c++builder
[C++ Avertissement] CFtpServer.h(59): W8017 La redéfinition de 'MAX_PATH' n'est pas identique
[C++ Erreur] CFtpServer.h(63): E2209 Impossible d'ouvrir le fichier include 'unistd.h'
[C++ Erreur] CFtpServer.h(65): E2209 Impossible d'ouvrir le fichier include 'pthread.h'
[C++ Erreur] CFtpServer.h(66): E2209 Impossible d'ouvrir le fichier include 'sys/socket.h'
[C++ Erreur] CFtpServer.h(67): E2209 Impossible d'ouvrir le fichier include 'netinet/in.h'
[C++ Erreur] CFtpServer.h(68): E2209 Impossible d'ouvrir le fichier include 'netinet/ip.h'
[C++ Erreur] CFtpServer.h(69): E2209 Impossible d'ouvrir le fichier include 'arpa/inet.h'
[C++ Erreur] CFtpServer.h(481): E2451 Symbole 'PATH_MAX' non défini
[C++ Erreur] CFtpServer.h(486): E2303 Nom de type attendu
[C++ Erreur] CFtpServer.h(486): E2139 ; manquant dans la déclaration
[C++ Erreur] CFtpServer.h(510): E2451 Symbole 'PATH_MAX' non défini
[C++ Erreur] CFtpServer.h(516): E2303 Nom de type attendu
[C++ Erreur] CFtpServer.h(516): E2139 ; manquant dans la déclaration
[C++ Erreur] CFtpServer.h(621): E2451 Symbole 'PATH_MAX' non défini
[C++ Erreur] CFtpServer.h(622): E2451 Symbole 'PATH_MAX' non défini
[C++ Erreur] CFtpServer.h(698): E2303 Nom de type attendu
[C++ Erreur] CFtpServer.h(698): E2139 ; manquant dans la déclaration
[C++ Erreur] CFtpServer.h(592): E2268 Appel à une fonction non définie 'close'
[C++ Erreur] Unit1.cpp(103): E2268 Appel à une fonction non définie 'usleep'
[C++ Avertissement] Unit1.cpp(106): W8066 Code inatteignable
realic Messages postés 16 Date d'inscription jeudi 16 novembre 2006 Statut Membre Dernière intervention 29 janvier 2016
4 mai 2007 à 09:58
Salut, ton code a l'air très bien, mais dans l'exemple, je ne parviens pas à comprendre comment lancer un client et un serveur.
En sachant que moi, je souhaite me connecter à un serveur distant, et récupérer des fichiers (ou des parties de fichiers) sur le serveur. Est-ce possible ?
Dans ce cas, aurais-tu un client simple à disposition, car j'ai un peu de mal avec ton code ?

Merci d'avance.
brunop976 Messages postés 1 Date d'inscription mercredi 30 juin 2004 Statut Membre Dernière intervention 3 avril 2006
3 avril 2006 à 18:32
bonjour,

visiblement ca marche pas en mode passif,
en pas sur le Wan en mode actif (mais la j'ai peut être pas tout compris !!!)


j'ai fait le test suivant : 2PCs en LAN ;
Le PC1 execute le serveur
PC1: run Example.exe
Le PC2 est le client !
Sur mon routeur vers l'exterieur j'ai forwardé le port 21 sur le PC1 j'ai essayé forwardé d'autre port sans succès !!!.

1) PC2: FTP (filezilla mode actif) vers PC1 par adresse LAN : test OK ;
2) PC2: FTP (filezilla mode passif) vers PC1 par adresse LAN : test NOK ;impossible de remonter la commande LIST
3) PC2: FTP (filezilla mode actif ou passif) vers par WAN ; NOK

ftp de la ligne de commande windows qui est en mode actif

1) FTP vers PC1 par adresse LAN : Test OK
2) FTP vers PC1 par adresse WAN : ERREUR 501 PORT ADDRESS DOES NOT MATCH ORIGINATOR


Question:

Je Fais Comment pour faire marcher ce serveur ?
Il serait interessant de debrousailler ce prblm car j'ai rien trouvé sur le net !!
A+
juju_browser Messages postés 8 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 novembre 2005
28 déc. 2005 à 15:36
merci d'avoir posté!
voila les modifications ont été faites, et le code mis a jour.

theBrowser
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
22 déc. 2005 à 18:42
[Good]
int main(int argc, char * argv[])
{
// ...
}
[Bad]
int main(char ** argv, int argc)
{
// ...
}

tu utilise la librairie Winsock version 2(ws2_32) mais demande la version 1
- WORD wVersionRequested = MAKEWORD( 1, 1 );

c'est pas très cohérent ... use MAKEWORD(2, 0) ou encore: WINSOCK_VERSION
en incluant <winsock2.h>(pour ws2_32), WINSOCK_VERSION est définie comme suit:
#define WINSOCK_VERSION MAKEWORD(2, 0)
je te conseil fortement d'utilise la version deux, la version un va disparaitre(elle se fait vieille)

#include <winsock2.h>
#pragma comment(lib, "ws2_32")
WSAStartup( MAKEWORD(2, 0), &wsaData )

au fait, en incluant <winsock2.h>, pas la peine d'inclure aussi <windows.h>
<winsock2.h> inclut déjà <windows.h> ...

WSAStartup() retourne zéro(0) si aucune erreur, sinon le code d'erreur, il serait peut-être bon de connaître l'erreur si WSAStartup() échoue ...

----------------------------------------
// sans .h en C++
#include <cstdlib> // pas <stdlib.h>
#include <cstdio> // pas <stdio.h>
#include <cctype> // pas <ctype.h>
#include <cstring> // pas <string.h>
#include <ctime> // pas <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <malloc.h> // perso, j'vois pas l'utilité de <malloc.h> ici ... il te sert à quoi!?
------------------------------------

tu as pleins de:
char * xyz = new char[abc];
// ...
delete xyz;

il te manque les [](crochets)

char * xyz = new char[abc];
// ...
delete [] xyz;

en C/C++ tu peux considerer les chaines de caractères comme des array(tableaux), donc il faut obligatoirement les crochets( [] ) pour la libération d'la mémoire ...
si tu utilise les crochets( [] ) pour ton new, alors il te faut obligatoirement les crochets( [] ) pour ton delete aussi ...

dans ton ::StartListening() ... si bind()/listen() failed, ferme ton socket, sinon il reste open ...

while( ( a = strchr( pszPath, '\\') ) != NULL )
*a = '/';

-- ca serait pas plus simple & rapide un:

for (a = pszPath; *a != '\0'; ++a)
{
if ( *a == '\\' )
{
*a = '/';
}
}

-- avec ton while() plus haut, tu recommence toujours la recherche du début, pas très rapide ...

tes flags « READFILE, WRITEFILE, ... » ne sont pas fonctionnels, ca doit être des puissances de 2(incluant le 1)
- 1*2=2*2=4*2=8*2=16*2=32*2=64*2=128*2=256...
- 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, ...
- 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, ...

bool CFtpServer::SetUsetPriv( struct CFtpServer::UserNode *User, unsigned long ulPriv )
{
// Si ((NewFlags & ~(AllFlags)) == 0) Alors
// ...
// FinSi
if ((ulPriv & ~(READFILE|WRITEFILE|DELETEFILE|LIST|CREATEDIR|DELETEDIR)) == 0)
{
User->ulPriv = ulPriv;
return true;
}
return false; // bad flags ...
}

if (ulPriv & READFILE)
{
// pas besoin de: if ((xyz->ulPriv & READFILE) == READFILE) ...
// si les flags sont valides
}

etc...
etc...
etc...

sinon, c'est pas si mal, mais faudrait reviser et tout corriger par contre ...


~(.:: NitRic ::.)~
juju_browser Messages postés 8 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 novembre 2005
18 nov. 2005 à 21:43
Salut,
dsl, j ai verifié, recompilé, et j'ai pa eu d'erreur.
T'aurais pas fait une modification du code qui aurai entrainer ce message ?

theBrowser
anonyme_man_in_this_world Messages postés 161 Date d'inscription samedi 25 juin 2005 Statut Membre Dernière intervention 1 août 2006
18 nov. 2005 à 09:40
source qui me parait interressante mais que j'ai pas

pu compiler avec Visual C++ 6.0 ,le message d'erreur

suivant est generé :
main.obj : error LNK2001: unresolved external symbol "public: bool __thiscall CFtpServer::SetPortA(unsigned short)" (?SetPortA@CFtpServer@@QAE_NG@Z)
merçi d'avance .
Taron31 Messages postés 199 Date d'inscription vendredi 16 avril 2004 Statut Membre Dernière intervention 28 février 2008
11 nov. 2005 à 18:41
Oui c'est moi qui ait voté j'aurais dû mettre plus en y repensant, désolé.
Parce que ton code est bien codé, je trouve ça propre, sympa quoi et tout ça dans une classe...
juju_browser Messages postés 8 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 novembre 2005
11 nov. 2005 à 16:37
C'est exactement ca.

sinon, est-ce que c'est toi qui a voté ?
si tel est le cas, puis-je savoir ce qui t'as motivé à mettre 7.
Taron31 Messages postés 199 Date d'inscription vendredi 16 avril 2004 Statut Membre Dernière intervention 28 février 2008
11 nov. 2005 à 16:25
Oui en relisant j'avais compris :-)
Et apres tu envoies les données mode passif via DataSock que tu viens d'ouvrir dans OpenDataConnection, n'est-ce pas ?
juju_browser Messages postés 8 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 25 novembre 2005
11 nov. 2005 à 15:25
c'est simple:
j'accepte la conection, et je met cette nouvelle conection dans une socket
puis je ferme la socket qui ecoutait

là ou t'as pas compris, c'est que y a 2 sockets: celle ki ecoute, et celle de la nouvelle connexion

theBrowser
Taron31 Messages postés 199 Date d'inscription vendredi 16 avril 2004 Statut Membre Dernière intervention 28 février 2008
11 nov. 2005 à 15:10
Salut, ton code a l'air très sympa.
Juste une chose que je comprends pas, c'est en ode passif, t'as mis ce code :

if( Client->eDataMode == Mode_PASV ) {

SOCKET sTmpWs;
struct sockaddr_in sin; int sin_len = sizeof(struct sockaddr_in);

sTmpWs = accept( Client->DataSock, (struct sockaddr *) &sin, &sin_len);
closesocket( Client->DataSock );
Client->DataSock = sTmpWs;
if( sTmpWs == INVALID_SOCKET )
return false;
return true;

pour quoi tu acceptes une connection, tu la fermes, et tu sauvegardes le socket ouvert ?
Merci
Rejoignez-nous