Передача файлов с 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? Я пробовал recv с флагом, установленным в MSG_OOB, но затем я получаю сообщение об ошибке «Неверный аргумент». Я был бы рад, если бы кто-то мог дать мне подсказку или пример того, как сделать это правильно, поскольку я, кажется, не могу понять это сам.

Спасибо,

Джон

1

Решение

FTP использовать два соединения. Первое — это командное соединение, в вашем случае это clie_sock. Команда «ABOR» должна быть получена через нее. Вы получите его так же, как получили команду «RETR».
Для получения файла клиент устанавливает соединение данных с вашим сервером (сокет c_data_sock). Он не будет открыт, пока клиент не подключится, так что это ответ на ваш второй вопрос. Вы не можете запустить клиент после того, как сервер выполнит эту функцию. Первый клиент отправляет команду ‘retr’ на ваш командный сокет. Затем ваш сервер ждет нового соединения от клиента (после отправки ему данных ip и port). Затем клиент подключается (теперь у вас есть готовый c_data_sock) и отправляет все данные в этот сокет, которые, в свою очередь, принимаются клиентом.

Вам, вероятно, нужно больше узнать о сети в целом, если вы чувствуете, что не понимаете этого. Я предпочитаю это: http://beej.us/guide/bgnet/

Также у вас есть утечка памяти здесь, после того, как вы выделите массив с

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

вам нужно удалить его с помощью

delete [] file_name;

В противном случае file_name будет рассматриваться как простой указатель, а не как массив, поэтому большая часть памяти массива будет сохраняться вашим приложением, что плохо, особенно при создании сервера.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]