[英]Read from socket until \r\n in Java
I want to implement a POP3 client. 我想实现一个POP3客户端。 I know that in POP3 protocol, each message ends with
\\r\\n
. 我知道在POP3协议中,每个消息都以
\\r\\n
结尾。 I want to write a recvuntil
method in Java, which will be able to receive a whole message at once. 我想用Java编写
recvuntil
方法,该方法将能够立即接收整个消息。
It super easy in Python: 在Python中超级简单:
def recv_all_until_ver3(s, crlf):
data = ""
while data[-len(crlf):] != crlf:
data += s.recv(1)
return data
However, when I tried to do the same in Java: 但是,当我尝试在Java中执行相同操作时:
class JavaApplication1 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException {
// TODO code application logic here
String serverAddress = "interia.pl";
int port = 110;
Socket s = new Socket(serverAddress, port);
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
String answer = "";
while (!answer.contains("\r\n")) {
answer = input.readLine();
System.out.println(answer);
}
}
}
It receives one message and hands instead of end itself. 它收到一条消息并举手而不是结束。 Is there any way to implement this method in Java?
有什么方法可以用Java实现此方法吗? Can I just read characters one by one, instead of whole line until I find
\\r\\n
in my message? 在消息中找到
\\r\\n
之前,我可以只逐个而不是整行地读取字符吗? Thank you. 谢谢。
The Python code reads one octet at a time, immediately appends it to answer
and signals it's done if at the current iteration answer
ends with CRLF
. Python代码一次读取一个八位位组,立即将其附加到
answer
,如果当前迭代的answer
以CRLF
结尾,则表明已完成。
The Java code hangs because BufferedReader.readLine()
returns the line content after stripping the line termination. Java代码挂起,因为
BufferedReader.readLine()
在剥离行终止后返回行内容。 At this point answer
does not contain CRLF
, so readLine()
is called once again, and since the stream is not closed from the other end (your program would then throw a NullPointerException
) and you have an infinite read timeout (you would see a SocketTimeoutException
), it hangs, forever waiting for the next line. 此时
answer
不包含CRLF
,因此再次调用readLine()
,并且由于没有从另一端关闭流(您的程序随后将抛出NullPointerException
),并且您有无限的读取超时(您将看到一个SocketTimeoutException
),它会挂起,永远等待下一行。
The correct version is 正确的版本是
Socket socket = connect(); // Implement this
Scanner scanner = new Scanner(new InputStreamReader(socket.getInputStream(), "ASCII"));
scanner.useDelimiter("\r\n");
String response = scanner.nextLine();
socket.close();
Notes: 笔记:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.