2013-05-10 154 views
1

我不确定有关ftp文件传输的一些事情。我正在编写一个ftp服务器,我正试图弄清楚如何使文件传输正常工作。到目前为止,它有某种程度上的作用,但我有一定的疑问。这里是我的文件传输功能(只能检索到目前为止):FTP服务器文件传输

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); 
} 

所以一个问题是数据传输本身。我不完全确定它应该如何工作。现在,它的工作原理如下:服务器将所有数据发送到c_data_sock,关闭此套接字,然后客户端开始执行某些操作。客户端在服务器发送数据时不应该收到数据吗?另一个问题是abor命令。我应该如何接受abor命令?我试着用设置为MSG_OOB的标志recv,但后来我收到一个错误,提示“无效参数”。我会很高兴,如果有人能给我一个提示或如何做对的例子,因为我似乎无法自己弄清楚。

感谢,

约翰

+0

任何不使用'libftp或libCurl'的理由? – billz 2013-05-10 10:21:46

+0

我天真地会与“他正在学习” – 2013-05-10 14:04:13

+0

非常感谢您的建议,但这是一个类的任务,我不能使用任何额外的库。不过,我可以看看源代码。 – user2274361 2013-05-10 14:11:14

回答

0

FTP将两个连接。首先 - 是命令连接,在你的情况下它是clie_sock。尽管如此,应该收到'ABOR'命令。您将按照收到'RETR'命令的方式接收它。 接收文件客户端与您的服务器建立数据连接(c_data_sock套接字)。它不会被打开,直到客户连接,所以这是你的第二个问题的答案。服务器执行此功能后,您无法启动客户端。第一个客户端将'retr'命令发送到您的命令套接字。然后你的服务器等待来自客户端的新连接(发送给他数据IP和端口后)。然后客户端连接(现在您已准备好c_data_sock)并将所有数据发送到该套接字,然后由客户端接收。

如果您觉得自己不理解,可能需要详细了解有关网络的更多信息。我喜欢这一个:http://beej.us/guide/bgnet/

你也有内存泄漏在这里,您分配使用

delete [] file_name; 

否则FILE_NAME将被视为与

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

一个数组,你需要将其删除后作为一个简单的指针,而不是一个数组,因此大多数数组内存将由您的应用程序保留,这在创建服务器时尤其糟糕。

+0

感谢您的回答。所以对于abor的接收,我应该在send函数之后有一个recv函数来检查客户端是否发送了abor?那么我需要添加超时到那个recv,所以循环可以继续或有任何其他方式?顺便说一句,当我中止文件传输时,服务器不会收到任何东西。 – user2274361 2013-05-10 13:30:17