如何知道FTP欢迎邮件的末尾(How to know the end of FTP Welcome

2019-08-01 23:52发布

我的问题是,我要创建一个FTP客户端,到目前为止,它的工作完美无缺,除了一个小细节,那一直缠着我。 我需要知道FTP欢迎消息多少行跨越......这是不能接受!

    private Socket connection;
    private PrintWriter outStream;
    private Scanner inStream;

public void InitiateConnection() throws IOException 
{
    log.Info(this, "Initiating connection to host: " + host + ":" + port);
    connection = new Socket(host, port);
    log.Info(this, "Connection initiated.");
    outStream = new PrintWriter(connection.getOutputStream(), true);
    inStream = new Scanner(connection.getInputStream());
    Listen();
    Listen();    
    Listen();
}

public String Listen() throws IOException
{
    if(connection == null)
        throw new IOException("Connection not initiated yet");
    String response = inStream.nextLine();
    log.Info(this, "Response: " + response);
    return response;
}

这是简单的设置,我已经离开了所有其他的代码,因为它没有任何与我的问题。

我曾尝试多东西来尝试实现这一目标。 失败解决方法1:

String response = "";
while(response != null)
    Listen();

失败解决方法2:

while(connection.getInputStream().available > 0)
    Listen();

和无数人......但无论它不工作,或者方法阻塞并等待新的输入。 我甚至试图与超时,但并不完美工作之一,它不是这一问题的妥善解决...

我需要能够得到从FTP服务器整个欢迎消息,不知道量线......所以我既可以得到这样的:

Response:   220-FileZilla Server version 0.9.39 beta
Response:   220-written by Tim Kosse (Tim.Kosse@gmx.de)
Response:   220 Please visit http://sourceforge.net/projects/filezilla/

还有这个:

Response:   220-FileZilla Server version 0.9.40 beta
Response:   220 Welcome to Andrés FTP Server

Answer 1:

如果你有消息仔细看,你会发现所有,但最后几行有一个-状态代码后面。 最后一行有 然而,这表明,好了,最后一行。

你可以读到,在RFC 959 ,第4.2节:

因此,对于多行回复格式是第一线将与所需的确切答复代码开始,紧跟一个连字符,“ - ”(也称为减号),然后是文本。 最后一行将使用相同的代码开始,通过空间,可选择一些文本,并在Telnet结束行代码紧随其后。

没有什么说一下第二至倒数第二行,但它是合乎逻辑的,它们具有相同的格式,第一个1。


更新:FTP协议似乎受到严重的记载,但我发现了另一个参考,说明我一样上面:

在TCP / IP指南中提到,

这是可能的答复包含文本的多行。 在这种情况下,每行的答复代码开始,所有的线,但最后有答复代码和回复文本之间的连字符,以指示答复仍在继续。 最后一行有答复代码和回复文本之间的空间,就像一个单行答复。 这种设施通常被用来提供附加的响应信息的用户登录后,通过230应答码。



Answer 2:

您是否尝试过这样的吗?

    StringBuilder response = new StringBuilder();
    BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    do {            
        response.append(br.readLine());                                     
    }
    while (br.ready());

而BufferedReader中的准备()方法:

判断此流是否已准备好被读取。 一种具有缓冲的字符流准备好,如果缓冲器不是空的,或者如果基础字符流已准备就绪。
返回:
真,如果下一个read()保证不会阻塞输入,否则返回假。 请注意,返回false并不保证阻塞下一次读取。

它实际上是一个阅读器的方法 。

更新:

作为glglgl指出,有两种类型的FTP响应:

  • “单行”的反应(我的术语)
  • 多行响应(规范的术语)

正如我在评论说,火起来FIlleZilla,连接和观察记录(最好是比较符合规范确定指标的输出命令),你会看到为什么“单行”被引用。

在某些FTP服务器实现上面的代码可以工作,但它会surley无法正常工作在所有的实现,因为它不正确执行协议的客户端部分。 这是更新的版本:

String response;
List<String> responseList = new ArrayList<String>();  
boolean isMultilineStart = false, isMultilineEnd = false;
String mlCode = null;
do {            
   responseList.add(br.readLine());                           
   if (!isMultilineStart) {
        isMultilineStart = responseList.get(responseList.size()-1).matches("\\d\\d\\d-.*");                
        mlCode = responseList.get(responseList.size()-1).substring(0,3);
   }
   else {
       isMultilineEnd = responseList.get(responseList.size()-1).startsWith(mlCode+" ");
   }
}
while (br.ready() || (isMultilineStart && !isMultilineEnd));   
response = Arrays.deepToString(responseList.toArray());


文章来源: How to know the end of FTP Welcome message