2017-08-04 9 views
0

私自身のJava FTPサーバーを作成します。最近まで、私は制御telnet接続をデバッグするためにPUttYを使用しましたが、すべてはうまく見えました - 私は成功した双方向通信を持っていました。今、私はFileZillaでサーバをデバッグしようとしていますが、テキストを読んだりサーバに送信したりしないので、何かを待っているだけです。 コントロール接続クラスFileZillaは私のJava FTPサーバーからのコマンドに反応しません

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 ... ステータス:接続が確立され、ウェルカムメッセージを待っています。

答えて

2

writeBytesを表示していません。だから私はあなたがメッセージをクライアントに送信した後に\r\nを送信していないと推測できるだけです。特にウェルカムメッセージの後に。だからFileZillaはFTPクライアントがやっているように永遠にそれを待っています。

+0

'writeBytes'は' DataOutputStream'で実装されていますので、何も変更しませんでした。 '\ r \ n'はとても重要ですか? –

+0

私は 'IOProcessing.writeBytes'を意味します –

+1

もちろん、それは重要です! FTPクライアントがメッセージの終わりをどのように識別できるのでしょうか? –

関連する問題