[C++] FTP client problem (winsock) [Archive] - C Board

PDA

View Full Version : [C++] FTP client problem (winsock)


Niekie
10-19-2003, 08:16 AM
Hey all, I have a little question.
I'm making a ftp program trough winsock.
It connects fine etc... but it wont login correctly to the ftp.
Sometimes when it sends the "USER <username>" to the ftp, the ftp says the username is ok and asks for a password.
But most of the time, the ftp doesnt respond to what I send to it.
And when it says the username is ok and I send the password "PASS <password" it wont respond too :(
Smth is wrong in the section of the code that is red.
I dont have a clue what's wrong. Could anybody help me?
Thanks, Niek



#include <winsock2.h>
#include <iostream.h>
#include <string.h>

int main()
{
WSADATA wsaData;
WORD wVersionRequested;
struct hostent *pTarget;
struct sockaddr_in sock;
char host[16];
char* target;
int port;
const int RECVBUF = 1024;
char buf[RECVBUF];
char buffer[RECVBUF];
char user[50];
char pass[50];
SOCKET mysocket;

cout << "Give here the IP address: " << endl;
cin >> host;
target = host;
cout << "Give here the port:" << endl;
cin >> port;
cout << "Give here the username:" << endl;
cin >> user;
cout << "Give here the password:" << endl;
cin >> pass;

//Making a connection...

wVersionRequested = MAKEWORD(1, 1);
if (WSAStartup(wVersionRequested, &wsaData) < 0) return -1;

mysocket = socket(AF_INET, SOCK_STREAM, 0);
if(mysocket==INVALID_SOCKET)
{
cout << "Socket error!\r" << endl;
exit(1);
}

cout << "Resolving Hostnames..." << endl;
if ((pTarget = gethostbyname(target)) == NULL)
{
cout << "Resolve of " << host << " failed" << endl;
exit(1);
}

memcpy(&sock.sin_addr.s_addr, pTarget->h_addr, pTarget->h_length);
sock.sin_family = AF_INET;
sock.sin_port = htons((USHORT)port);

cout << "Connecting..." << endl;
if ( (connect(mysocket, (struct sockaddr *)&sock, sizeof (sock) )))
{
cout << "Couldn't connect to host." << endl;
exit(1);
}
cout << "Connected" << endl;
recv(mysocket, buf, sizeof(buf), 0); //winsock ready etc...


//logging in...


cout << "Logging in..." << endl;
char* tempp = "USER ";
char users[55];
strcpy(users, tempp);
strcat(users, user);
char* userss = users;
send(mysocket, userss, sizeof(buffer), 0);
recv(mysocket, buf, sizeof(buf), 0);

if(buf != 0)
{
goto pass;
}
else
{
cout << "Server not responding, press enter to exit" << endl;
cin.get();
closesocket(mysocket);
WSACleanup();
exit(1);
}

pass:
char password[55];
char* temp = "PASS ";
strcpy(password, temp);
strcat(password, pass);
char* passwordd = password;
send(mysocket, passwordd, sizeof(buffer), 0);
recv(mysocket, buf, sizeof(buf), 0);
recv(mysocket, buf, sizeof(buf), 0);
if(strcmp(buf, "230 User logged in, proceed.")== 0)
{
cout << "Password is correct, succesfully logged in" << endl;
goto end;
}
else
{
cout << "The password is invalid, press enter to exit" << endl;
cin.get();
closesocket(mysocket);
WSACleanup();
exit(1);
}

end:
closesocket(mysocket);
WSACleanup();
return 0;
}

Salem
10-19-2003, 08:27 AM
> strcpy(users, tempp);
> strcat(users, user);
You also need to append say "\n\r", or whatever the FTP RFC (say ftp://ftp.isi.edu/in-notes/rfc959.txt) says about end of line characters

> char* userss = users;
This adds nothing - you can say send(users just as easily

> send(mysocket, userss, sizeof(buffer), 0);
You don't have sizeof(buffer) chars to send, you have strlen(users) chars to send
Additionally, send() returns a result - namely the number of chars sent. Checking this would be a start.

> recv(mysocket, buf, sizeof(buf), 0);
You're expecting too much if you expect a complete answer in the time it takes to make 2 function calls. You need to allow for some delay between sending the message and expecting a reply from a remote site.
Again, recv() returns a result.
Also, recv() does not add a '\0' to the end of the buffer to make it a proper 'C' string, which makes your use of strcmp() later on suspect.
Nor does recv() guarantee to receive a whole line in a single call - reassembly of data following network fragmentation is your responsibility.

> if(buf != 0)
buf is an array, therefore this is always true.
If you were trying to examine the first char, it would be if ( buf[0]

Niekie
10-19-2003, 09:23 AM
Thanks, it seems that I did quite allot wrong :(
Will modify the code and look if it works :D