BufferedReader read()和readLine()都试图从POP3服务器获取响应

时间:2015-04-10 13:55:32

标签: java network-programming pop3

我正在开发一个处理与POP3服务器交互的小型终端应用程序。但是,我遇到了BufferedReader块中read()和readLine()的问题。我的初始尝试使用了readLine(),但是在SO和其他网站上阅读之后,我发现服务器没有返回相应的字符来标记该行的结尾,所以我尝试使用read()。但出于某种原因,这也会阻止。

    Socket s = new Socket(InetAddress.getByName(this.HOST), 110);

    BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
    PrintWriter out = new PrintWriter(s.getOutputStream(), true);

    String res = in.readLine(); // This works fine
    System.out.println(res);

    res = "";
    char [] charRes = new char[1024];

    out.println("USER " + this.username);
    // res = in.readLine();
    in.read(charRes); // Does not work
    res = charRes.toString();
    System.out.println(res);

问题不在于服务器,因为我使用Telnet测试它并且它工作正常。我不确定我做错了什么,我很感激任何帮助。

我的客户端软件在Linux系统上运行,我正在连接到Windows服务器。

1 个答案:

答案 0 :(得分:0)

根据the documentationread(byte[])方法将阻塞,直到从流中读取至少一个字节。

为确保在调用read(byte[])方法之前有可用数据,您可以调用available()方法documented here

根据您的原始问题和随后的评论,主要问题似乎是由行结尾引起的。您已指示客户端在Linux上运行,其中标准行结尾为LF\n),但POP3 RFC明确要求每个命令由CRLF终止( \r\n)。请尝试使用out.println()documentation)方法,而不是使用\n(将自动使用系统行结尾PrintWriter.write(String))。

您似乎正在使用PrintWriter构造函数,autoFlush设置为true。这意味着在使用println()方法时会自动刷新您的流,但是,在使用write()方法时,它不会自动刷新,因此您还需要添加对{{1}的调用}。同样,建议参考the documentation。更新后的代码如下所示:

flush()

您可能需要考虑类似地更新输入流中的读取,以确保您不必从输入中手动删除out.write("USER " + this.username + "\r\n"); out.flush(); 个字符(各种\r方法将使用/丢弃客户端在Linux上运行时readLine()但不是\n