Хобрук: Ваш путь к мастерству в программировании

Реализация собственного ftp-сервера: ответ на команду LIST

Пытаюсь реализовать свой ftp-сервер без всяких библиотек на Java. Для тестирования своего сервера я использую FTP-клиент FileZilla. Проблема в том, что я не могу отправить список файлов в текущем каталоге через соединение для передачи данных (или, другими словами, я не могу реализовать FTP-команду LIST). Пробовал и активный и пассивный режимы.

Вот вывод FileZilla:

Command:    PASV
Response:   227 Entering Passive Mode (192,168,0,87,125,63)
Command:    LIST
Response:   150 Opening BINARY mode data connection.
// Here I'm trying to send list of files through data connection
Response:   226 Transfer complete.
Error:  Connection timed out
Error:  Failed to retrieve directory listing

Вот моя реализация команд LIST и PASV:

public class FTPCommandSocket implements Runnable {

    Socket command_socket;
    Socket data_socket = null;
    FTPDataSocket ftpds = null;
    ServerSocket ss = null;
    // ...
    @Override
    public void run() {
        try {
            // Send response to the client.
            sendResponse("220 WELCOME\n");

            while(from_client_command.read(input_b) != -1)
            {
                String input = new String(input_b);
                String cmd = parseInput(input);
                switch(cmd) {
                    // ... (other commands)
                    case Command.PASV:
                        sendResponse("227 Entering Passive Mode (192,168,0,87,125,63)\n");
                        ss = new ServerSocket(125 * 256 + 63);
                        data_socket = ss.accept();
                        ftpds = new FTPDataSocket(data_socket);
                    break;
                    case Command.LIST:
                        sendResponse("150 Opening BINARY mode data connection.\n");
                        ftpds.sendFilesList(cur_path);
                        Thread.sleep(500);
                        sendResponse("226 Transfer complete.\n");
                    break;
                    //... (other commands)
                    default:
                        sendResponse("502 Command is not implemented.\n");
                }
            }
        } catch (...) {}
    }

    private void sendResponse(String string) throws IOException {
        to_client_command.write(string.getBytes());
        to_client_command.flush();
    }
}

Это класс подключения к данным:

public class FTPDataSocket {
    Socket data_socket;
    OutputStream to_client_data;
    InputStream from_client_data;
    private final byte[] input_b = new byte[15000];

    public FTPDataSocket(Socket s) throws IOException {
        this.data_socket = s;
        from_client_data = data_socket.getInputStream();
        to_client_data = data_socket.getOutputStream();
    }

    public void sendFilesList(String path) throws IOException {
        // Debug version: there are no real files yet.
        sendResponse("-rwxr-xr-x 1 100 100 14757 a.out\r\n");
    }

    private void sendResponse(String string) throws IOException {
        to_client_data.write(string.getBytes());
        to_client_data.flush();
        System.out.print(string);
    }
}

У вас есть идеи, что я делаю неправильно?

Заранее спасибо!

17.11.2014

  • Клиент не может получить список файлов. Его ответ: Время ожидания соединения истекло. Но сокет данных открыт, и список действительно отправлен. 18.11.2014

Ответы:


1

Проблема заключалась в том, что сокет не закрывался после отправки данных.

24.11.2014
  • Я часами искал ответ, почему СПИСОК не работал в моем случае. Моя реализация на C++, но логика та же. Закрытие сокета теперь позволяет мне вывести список содержимого. Спасибо. 16.05.2016
  • Новые материалы

    Понимание структуры каталогов Linux
    Структура каталогов Linux — это иерархическая организация файлов и каталогов в системе Linux. Понимание этой структуры важно для всех, кто хочет использовать Linux в качестве основной..

    Введение в SQLite3 в Python
    SQLite3 — это популярная и часто используемая программная библиотека для управления реляционными базами данных. Она портативна, быстра и проста в использовании, что делает ее отличным выбором..

    Как создать ORM в Node.js
    Что такое ОРМ? Проще говоря, система ORM — это метод, в котором вы используете объектно-ориентированную парадигму для создания сопоставления между приложением и базой данных для выполнения..

    Руководство для начинающих по обработке естественного языка .
    Обработка естественного языка — захватывающая и быстро развивающаяся область, которую можно охарактеризовать как сочетание лингвистики, информатики и искусственного интеллекта. Это помогает..

    Защитите свое приложение NodeJS с помощью веб-токенов JSON (JWT): руководство по аутентификации на основе токенов
    В современном мире веб-приложений безопасность важнее, чем когда-либо. Одним из наиболее важных аспектов защиты веб-приложений является аутентификация пользователей. Аутентификация на основе..

    Вводное руководство по аннотациям @PreAuthorize и @PostAuthorize в Spring Security
    Введение Spring Security — это мощная и настраиваемая среда аутентификации и контроля доступа для приложений Java, особенно тех, которые созданы с использованием среды Spring. Этот пост..

    От стартапов к успеху в индустрии наук о данных: 5 важных инструментов
    Постоянно растущие объемы данных сегодня играют решающую роль для каждой компании, которая хочет оставаться на вершине. Это означает использование технологий искусственного интеллекта ,..