【问题标题】:FileZilla won't react on commands from my java FTP serverFileZilla 不会对来自我的 java FTP 服务器的命令做出反应
【发布时间】:2017-08-04 13:54:10
【问题描述】:

我编写自己的 Java FTP 服务器。直到最近,我使用 PUttY 来调试我的控制 telnet 连接,一切似乎都很好——我成功地进行了双向通信。现在我尝试使用 FileZilla 调试我的服务器,但它似乎没有读取我的文本,也没有向服务器发送一些文本,所以它只是挂起并等待一些东西。 控制连接类

public class ControlConnection extends Thread {
private enum OperationMode {
    ACTIVE, PASSIVE
}
private final Map<String, Supplier<String>> COMMANDS;
private String[] userTokens;

private User user;
private String userLogin;
private boolean authenticated;
private boolean dataConnected;
private boolean userExists;
private final Socket socket;
private DataInputStream inputStream;
private DataOutputStream outputStream;
private DataConnection ftpSession;
private OperationMode operationMode;
private String errorMessage;

public ControlConnection(Socket socket) {
    super(ControlConnection.class.toString());
    this.socket = socket;

    // constants initialization
    authenticated = false;
    dataConnected = false;

    // commands initialization
    COMMANDS = new HashMap<>();
    // commands init
}

@Override
public void run() {
    try {
        inputStream = new DataInputStream(socket.getInputStream());
        outputStream = new DataOutputStream(socket.getOutputStream());
        sendGreetings();
        IOProcessing.writeBytes(outputStream, pasvCommand());;
        boolean running = true;
        while (running) {
            sendGreetings();
            String input = IOProcessing.readBytes(inputStream);
            if (!(input.equals("")))
                System.out.println(input);
            if (!checkInput(input))
                continue;
            userTokens = input.split(" ");
            String command = userTokens[0].toUpperCase();
            String answer = COMMANDS.get(command).get();              
            outputStream.writeBytes(answer);
        }
    }
    catch (IOException e) {
        System.err.println(e);
        System.exit(-1);
    }
}
private boolean commonCheck() {
    // some checks
    return true;    
}
private String getErrorMessage() {
    return errorMessage;
}
public void sendGreetings() {
    String greetings = String.format("220 Control connection established: %s", getConnectionInfo());
    IOProcessing.writeBytes(outputStream, greetings);
}
public String getConnectionInfo() {
    String info = String.format("%s: %d %s",
            socket.getInetAddress().toString(), socket.getPort(), user != null ? user.getUsername(): "");
    return info;
}
// input/output proccessing functions
public boolean checkInput(String input) {
    // checks
    return true;
}

// commands functions
private String pasvCommand() {
    if (operationMode == OperationMode.PASSIVE) {
        errorMessage = "Already in passive mode.%n";
        return errorMessage;
    }
    String answer;
    new ListenToSocket().start();
    answer = String.format("227 Entering Passive Mode (%s, %d)",
        "127.0.0.1", DataConnection.PORT);
    operationMode = OperationMode.PASSIVE;
    return answer;
    }
private class ListenToSocket extends Thread {
    public ListenToSocket() {
    }

    @Override
    public void run() {
        try {
            ServerSocket ftpSocket =
                    new ServerSocket(DataConnection.PORT);
            ftpSession =
                    DataConnection.getDataConnection(ftpSocket.accept());
            if (ftpSession != null) {
                ftpSession.start();
                dataConnected = true;
                String greetings = "Data connection established: " + ftpSession.getConnectionInfo();
                IOProcessing.writeBytes(outputStream, greetings);
            } else {
                dataConnected = false;
            }
        } catch (IOException e) {
            System.out.print(e);
        }
    }
}

此外,服务器没有获取用户凭据,在 FileZilla 中输入 - 来自服务器的输入始终为空 IOProcessing类

public class IOProcessing {
private static final Charset UTF8_CHARSET;
static {
    UTF8_CHARSET = Charset.forName("UTF-8");
}

public static String readBytes(DataInputStream inputStream) {
    String result = "";
    try {
        int len = inputStream.available();
        if (len == 0) {
            return result;
        }
        byte[] byteInput = new byte[len];
        inputStream.readFully(byteInput, 0, len);
        result = new String(byteInput, "UTF-8").trim();
    } catch (IOException e) {
        System.err.println(e);
    }
    return result;
}

输出 FileZlla 日志 状态:解析本地主机的地址 状态:正在连接到 [::1]:21... 状态:连接已建立,等待欢迎消息。

【问题讨论】:

    标签: java ftp


    【解决方案1】:

    您没有向我们展示writeBytes。所以我只能猜测你在发送给客户端的消息之后没有发送\r\n。特别是在欢迎信息之后。所以 FileZilla 一直在等待它,就像任何 FTP 客户端都会做的那样。

    【讨论】:

    • writeBytesDataOutputStream 中实现,所以我没有更改任何内容。发送\r\n 这么重要吗?
    • 我的意思是IOProcessing.writeBytes
    • 当然,这很重要! FTP 客户端如何识别消息的结尾?
    • 现在可以了,非常感谢!奇怪的是,没有 `\r` 的 PUttY 工作得很好
    • PuTTY 不是 FTP 客户端。 - 在尝试实现 FTP 服务器之前,您应该阅读 FTP 规范。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    • 2017-06-11
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多