简体   繁体   中英

FTP server file transfer

I am uncertain about a few things regarding ftp file transfer. I am writing an ftp server and I am trying to figure out how to make the file tranfer work correctly. So far it works somehow but I have certain doubts. Here is my file transfer function (only retrieve so far):

void RETRCommand(int & clie_sock, int & c_data_sock, char buffer[]){
ifstream file;  //clie_sock is used for commands and c_data_sock for data transfer
char *file_name, packet[PACKET_SIZE]; //packet size is 2040
int packet_len, pre_pos = 0, file_end;
file_name = new char[strlen(buffer + 5)];
strcpy(file_name, buffer + 5);

sprintf(buffer, "150 Opening BINARY mode data connection for file transfer\r\n");

if (send(clie_sock, buffer, strlen(buffer), 0) == -1) {
    perror("Error while writing ");
    close(clie_sock);
    exit(1);
}

cout << "sent: " << buffer << endl;

file_name[strlen(file_name) - 2] = '\0';
file.open(file_name, ios::in | ios::binary);

if (file.is_open()) {

    file.seekg(0, file.end);
    file_end = (int) file.tellg();
    file.seekg(0, file.beg);

    while(file.good()){

        pre_pos = file.tellg();
        file.read(packet, PACKET_SIZE);

        if ((int) file.tellg() == -1)
            packet_len = file_end - pre_pos;
        else
            packet_len = PACKET_SIZE;

        if (send(c_data_sock, packet, packet_len, 0) == -1) {
            perror("Error while writing ");
            close(clie_sock);
            exit(1);
        }

        cout << "sent some data" << endl;

    }

}
else {
    sprintf(buffer, "550 Requested action not taken. File unavailable\r\n", packet);

    if (send(clie_sock, buffer, packet_len + 2, 0) == -1) {
        perror("Error while writing ");
        close(clie_sock);
        exit(1);
    }

    cout << "sent: " << buffer << endl;

    delete(file_name);
    return;
}

sprintf(buffer, "226 Transfer complete\r\n");

if (send(clie_sock, buffer, strlen(buffer), 0) == -1) {
    perror("Error while writing ");
    close(clie_sock);
    exit(1);
}

cout << "sent: " << buffer << endl;

close(c_data_sock);

delete(file_name);
}

So one problem is the data transfer itself. I am not exactly sure how it is supposed to work. Now it works like this: the server sends all the data to c_data_sock, closes this socket and then the client starts doing something. Shouldn't the client recieve the data while the server is sending them? And the other problem is the abor command. How am I supposed to recieve the abor command? I tried recv with flag set to MSG_OOB but then I get an error saying "Invalid argument". I would be glad if someone could give me a hint or an example of how to do it right as I don't seem to be able to figure it out myself.

Thanks,

John

Ftp use two connections. First - is command connection, in your case it is clie_sock. 'ABOR' command should be received though it. You going to receive it the same way you received 'RETR' command. To receive file client establishes data connection with your server ( c_data_sock socket ). It will not be opened till client connects, so this is the answer to your second question. You cannot start client after server executes this function. First client sends 'retr' command to your command socket. Then your sever waits new connection from client ( after sending him data ip and port ). Then client connects ( now you have your c_data_sock ready ) and sends all the data to that socket, which are in turn received by the client.

You probably need to read more about networking in general if you feel you don't understand it. I prefer this one: http://beej.us/guide/bgnet/

Also you have a memory leak here, after you allocate an array with the

file_name = new char[strlen(buffer + 5)];

you need to delete it using

delete [] file_name;

Otherwise file_name will be treated as a simple pointer, not an array, so most of array memory will be kept by your application which is bad especially when creating server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM