我正在开发一个处理与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服务器。
答案 0 :(得分:0)
根据the documentation,read(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
。