2017-08-04 77 views
0

我写我自己的Java FTP服务器。直到最近我使用PUttY来调试我的控制telnet连接,一切似乎都很好 - 我成功地进行了双向通信。现在我尝试用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客户端如何识别消息的结尾? –

相关问题