BufferedReader read() 和 readLine() 都在尝试从 POP3 服务器获得响应时挂起
BufferedReader read() and readLine() both hang trying to get a response from a POP3 server
我正在开发一个小型终端应用程序来处理与 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 服务器。
根据 the documentation,read(byte[])
方法将阻塞,直到从流中读取至少一个字节。
为了保证在调用read(byte[])
方法之前有数据可用,可以调用available()
方法,documented here.
根据你原来的问题和后续的评论,主要问题似乎是由行尾引起的。您已经指出客户端是 运行 on Linux,其中标准行结尾是 LF
(\n
) 但 POP3 RFC specifically requires each command to be terminated by CRLF
(\r\n
). Instead of using out.println()
(which will use your system line ending of \n
automatically), try using the PrintWriter.write(String)
(documentation) 方法。
您似乎在使用 PrintWriter
构造函数并将 autoFlush
设置为 true。这意味着您的流在使用 println()
方法时会自动刷新,但是,在使用 write()
方法时它不会自动刷新,因此您还需要添加对 [=25= 的调用].同样,建议参考 the documentation。更新后的代码看起来像这样:
out.write("USER " + this.username + "\r\n");
out.flush();
您可能需要考虑类似地更新您从输入流中读取的内容,以确保您不必从输入中手动删除 \r
个字符(各种 readLine()
方法将消耗 /当客户端在 Linux) 上运行时丢弃 \n
但不丢弃 \r
。
我正在开发一个小型终端应用程序来处理与 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 服务器。
根据 the documentation,read(byte[])
方法将阻塞,直到从流中读取至少一个字节。
为了保证在调用read(byte[])
方法之前有数据可用,可以调用available()
方法,documented here.
根据你原来的问题和后续的评论,主要问题似乎是由行尾引起的。您已经指出客户端是 运行 on Linux,其中标准行结尾是 LF
(\n
) 但 POP3 RFC specifically requires each command to be terminated by CRLF
(\r\n
). Instead of using out.println()
(which will use your system line ending of \n
automatically), try using the PrintWriter.write(String)
(documentation) 方法。
您似乎在使用 PrintWriter
构造函数并将 autoFlush
设置为 true。这意味着您的流在使用 println()
方法时会自动刷新,但是,在使用 write()
方法时它不会自动刷新,因此您还需要添加对 [=25= 的调用].同样,建议参考 the documentation。更新后的代码看起来像这样:
out.write("USER " + this.username + "\r\n");
out.flush();
您可能需要考虑类似地更新您从输入流中读取的内容,以确保您不必从输入中手动删除 \r
个字符(各种 readLine()
方法将消耗 /当客户端在 Linux) 上运行时丢弃 \n
但不丢弃 \r
。