简体   繁体   English

FTP服务器文件传输

[英]FTP server file transfer

I am uncertain about a few things regarding ftp file transfer. 我不确定有关ftp文件传输的几件事。 I am writing an ftp server and I am trying to figure out how to make the file tranfer work correctly. 我正在编写一个ftp服务器,并且试图弄清楚如何使文件传输正常工作。 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. 现在它是这样工作的:服务器将所有数据发送到c_data_sock,关闭此套接字,然后客户端开始执行操作。 Shouldn't the client recieve the data while the server is sending them? 服务器发送数据时,客户端不应该接收数据吗? And the other problem is the abor command. 另一个问题是abor命令。 How am I supposed to recieve the abor command? 我应该如何接收abor命令? I tried recv with flag set to MSG_OOB but then I get an error saying "Invalid argument". 我尝试将标志设置为MSG_OOB的recv,但随后出现错误消息“ Invalid arguments”。 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. ftp使用两个连接。 First - is command connection, in your case it is clie_sock. 首先-是命令连接,在您的情况下是clie_sock。 'ABOR' command should be received though it. 尽管应该接收“ ABOR”命令。 You going to receive it the same way you received 'RETR' command. 您将以与接收“ RETR”命令相同的方式接收它。 To receive file client establishes data connection with your server ( c_data_sock socket ). 要接收文件,客户端将与服务器建立数据连接(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. 第一个客户端将“ retr”命令发送到您的命令套接字。 Then your sever waits new connection from client ( after sending him data ip and port ). 然后,您的服务器等待来自客户端的新连接(向他发送数据ip和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. 然后客户端连接(现在您已经准备好了c_data_sock)并将所有数据发送到该套接字,然后由客户端接收。

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/ 我更喜欢这个: 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. 否则,file_name将被视为简单的指针,而不是数组,因此大多数数组内存将由您的应用程序保留,这很不好,尤其是在创建服务器时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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