Что такое протокол FTP?

«Что такое протокол FTP?» — вопрос из категории Сети, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

FTP (File Transfer Protocol) — это стандартный сетевой протокол прикладного уровня для передачи файлов между клиентом и сервером по TCP/IP. Он использует два отдельных соединения: управляющее (control connection) на порту 21 для команд и аутентификации, и соединение для данных (data connection), которое по умолчанию использует порт 20 в активном режиме.

Ключевые особенности:

  • Режимы работы: Активный (сервер сам подключается к клиенту для передачи данных) и пассивный (клиент подключается к серверу, что удобно при наличии фаервола на стороне клиента).
  • Безопасность: Классический FTP не шифрует ни команды, ни данные, что делает его уязвимым к перехвату трафика (MITM-атаки). Для безопасной передачи следует использовать FTPS (FTP over SSL/TLS) или SFTP (SSH File Transfer Protocol).
  • Аутентификация: Обычно по логину и паролю, передаваемым в открытом виде.

Пример реализации простого FTP-клиента на C++ (используя сокеты):

#include <iostream>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>

class SimpleFTPClient {
    int control_sock;
public:
    bool connect(const std::string& host, int port = 21) {
        struct hostent* server = gethostbyname(host.c_str());
        if (!server) return false;

        control_sock = socket(AF_INET, SOCK_STREAM, 0);
        struct sockaddr_in serv_addr;
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(port);
        memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);

        if (::connect(control_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
            return false;
        }
        // Читаем приветственный баннер от сервера
        char buffer[1024];
        read(control_sock, buffer, sizeof(buffer));
        return true;
    }

    void sendCommand(const std::string& cmd) {
        std::string full_cmd = cmd + "rn";
        send(control_sock, full_cmd.c_str(), full_cmd.size(), 0);
        char response[4096];
        int len = read(control_sock, response, sizeof(response)-1);
        response[len] = '';
        std::cout << "Ответ: " << response;
    }

    ~SimpleFTPClient() { if (control_sock) close(control_sock); }
};

// Использование:
// SimpleFTPClient client;
// client.connect("ftp.example.com");
// client.sendCommand("USER mylogin");
// client.sendCommand("PASS mypassword");

На практике для работы с FTP в C++ проектах часто используют библиотеки вроде libcurl или POCO Net.