Salve a tutti!
Nel procedere con lo studio delle socket windows ho voluto creare un programma client FTP per mettere alla prova ciò che avevo studiato.
Mi sono informato anche sul funzionamento dello scambio di informazioni fra client e server ftp e se ho capito bene:
Il server FTP è in ascolto sulla porta 21.
Il client si connette a tale porta per inviare e ricevere rispettivamente comandi e risposte.
Per il trasferimento di dati per i file invece è necessaria una seconda connessione che può essere in due modalità:
- attiva: (il client apre una porta locale (>1023) e la notifica al server tramite la connessione principale(comandi) e attende il server, a connessione stabilita il server esegue il binding sulla porta 20);
- passiva: (il server notifica al client la porta remota (>1023) comunicandola nel canale comandi in modo tale che il client possa aprire la connessione su tale porta).
Procedendo a piccoli passi ho iniziato il programma in questo modo:
Questo è l'output del programma:codice:#include <iostream> #include <winsock2.h> int initWsaData(int a, int b); //Init WSADATA int initSK(int af, int type, int proto); //Init socket int cnSK(int af, const char *ip, u_short port, SOCKET s); //Apri connessione socket int getSvMex(SOCKET s); //Riceve e controlla la ricezione cmd int sendClMex(SOCKET s); //invia e controlla il risultato dell'invio cmd int main() { UINT_PTR sk; //socket std::cout << "***************************\n"; if(initWsaData(2,2) != NO_ERROR) { std::cerr << "* WSADATA: ERRORE *\n"; return (1); } else { std::cout << "* WSADATA: Ok *\n"; } sk = initSK(2,1,6);// AF_INET SOCK_STREAM IPPROTO_TCP if(sk == INVALID_SOCKET){ std::cerr << "* SOCKET: ERRORE *\n"; WSACleanup(); return (2); } else { std::cout << "* SOCKET: OK *\n"; } if(cnSK(2,"INDIRIZZO_IP",21,sk) == SOCKET_ERROR) { WSACleanup(); closesocket(sk); std::cerr << "* CONNESSIONE: ERRORE *\n"; return (3); } else { std::cout << "* CONNESSIONE: ATTIVA *\n"; } std::cout << "***************************\n"; if(getSvMex(sk) <=0) { std::cerr << "ERRORE!\n"; WSACleanup(); closesocket(sk); return (4); } while(true) { if(sendClMex(sk)<= 0) break; if(getSvMex(sk) <= 0) break; } WSACleanup(); closesocket(sk); return (0); } int initWsaData(int a, int b) { WSADATA wsaData; int res; res = WSAStartup(MAKEWORD(a, b), &wsaData); return (res); } int initSK(int af, int type, int proto) { UINT_PTR res; res = socket(af, type, proto); return (res); } int cnSK(int af, const char *ip, u_short port, SOCKET s) { int res; sockaddr_in addr; addr.sin_family = af; addr.sin_addr.s_addr = inet_addr(ip); addr.sin_port = htons(port); res = connect(s, (SOCKADDR*)&addr, sizeof(addr)); return (res); } int getSvMex(SOCKET s) { char buf[256]; int by = 0; std::cout << "Attesa risposta: "; by = recv(s, buf, (int)strlen(buf), NULL); if(by < 0) { std::cout << "NESSUNA RISPOSTA!\n"; return (0); } if(by > 0) std::cout << buf; std::cout << std::endl; return (by); } int sendClMex(SOCKET s) { char buf[256]; int by = 0; std::cin.getline(buf, (int)strlen(buf)); by = send(s, buf, sizeof(buf), NULL); if(by < 0) { std::cerr << "\t\tErrore invio: " << buf << '\n'; return (by); } std::cout << "Inviato cmd : " << buf << '\n'; return (by); }
Poi rimane in attesa del cmd e ad esmpio scrivo USER xxxxxxxxx il server dopo pochi secondi mi risponde con:codice:************************** * WSADATA: OK * * SOCKET: OK * * CONESSIONE: ATTIVA * ************************** Attesa risposta: 220 XXXX Ftp Server (e a capo una sorta di simboli inconprensibili)
Il fatto che riesco a ricevere le risposte del server mi fà pensare che non ho proprio fatto una "schifezza"... ma allora quale/i possono essere i motivi per cui qualsiasi cmd che invio io non funzionano e sempre e comunque il server mi risponde con... lo steso messaggio di errore temporaneo ? Grazie a tutti quelli che risponderanno.codice:Attesa risposta: 421 Connection Closed, Timed Out. (e i simboli incomprensibili)

Rispondi quotando
,
), subito dopo l'invio, controllo il valore di ritorno di 'send()' e se maggiore di '0' raccoglie tramite 'std::cin.getline(buf, 256)' nella variabile 'char buf[256]' appunto e lo stampa... ed è ciò che io effettivamente inserisco... quindi al server FTP "in teoria" dovrebbe arrivare la stringa nel formato corretto ad esempio:
