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

Ответ

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.

Ответ 18+ 🔞

А, FTP, ёпта! Ну это ж классика, как батянин «Москвич» — дымит, скрипит, но иногда едет. Протокол для перекидывания файлов по сети, который старше, чем твои первые порно-картинки, скачанные на dial-up модеме.

Слушай, суть простая, но с подвохом. Работает он на двух портах, как будто у него раздвоение личности. Один канал (порт 21) — для болтовни, типа «эй, сервак, я тут, вот мой пароль». А второй (часто порт 20) — уже для самой передачи данных, то есть самих файлов. Это в так называемом активном режиме. Но тут есть хитрая жопа: если у тебя на компе стоит фаервол, он может такого серверного подключения испугаться и нахуй его не пустить. Поэтому придумали пассивный режим, где уже клиент сам лезет к серверу за данными. Удобно, но иногда голова болит от настройки.

А теперь главное, что ты должен понять, чувак: доверия к обычному FTP — ноль ебать. Это как кричать свой пароль от банка в переполненном автобусе. Ничего не шифруется! И логин с паролем, и сами файлы летят открытым текстом. Любой ушлый тип в той же сети может всё это перехватить. Поэтому если тебе дорога твоя информация, надо юзать либо FTPS (это когда поверх SSL/TLS, как в HTTPS), либо SFTP (это вообще поверх SSH, совсем другая история). Иначе будет вам хиросима с утечкой данных.

Ну а теперь, для полного погружения, смотри, как это выглядит в коде на плюсах. Чисто академический пример, чтобы понять механику. В жизни, конечно, берут готовые библиотеки вроде libcurl — не надо изобретать велосипед, который уже накрылся медным тазом.

#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 — это исторический артефакт, как кассетный магнитофон. Для внутренних, закрытых сетей, где всем похуй на безопасность, ещё сойдёт. Но чтобы в интернет что-то серьёзное выкладывать — ищи что-то зашифрованное. А то какой-нибудь пидарас шерстяной обязательно твои файлы стащит.