Reputation: 626
I want to implement a POP3 client. I know that in POP3 protocol, each message ends with \r\n
. I want to write a recvuntil
method in Java, which will be able to receive a whole message at once.
It super easy in 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:
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? Can I just read characters one by one, instead of whole line until I find \r\n
in my message? Thank you.
Upvotes: 0
Views: 2106
Reputation: 20885
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
.
The Java code hangs because BufferedReader.readLine()
returns the line content after stripping the line termination. 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.
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:
Upvotes: 1
Reputation: 3063
you can use the Scanner class (it accepts an InputStream
as a constructor param ) and set the delimiter using useDelimiter
method. to read messages that end with \r\n
Upvotes: 0