How to determine the end of a SMTP and POP response?
I am reading character by character of a socket response in a BufferedReader written from a socket that I am connecting to a SMTP and POP server. But how do I know if I have read until the end of the response to avoid having the read()
to hang for reading beyond what the server responded? The following code is how I am reading from the BufferedReader:
boolean endOfResponse = false;
while(!endOfResponse) {
c = in.read();
if ((c >= 32 && c < 127) || c == '\t' || c == '\r' || c == '\n') {
response.append((char)c);
//The following check has a problem: If the response has multiple lines, the other lines will not be read.
if(c == '\n') endOfResponse = true;
}
}
For instance, in POP, when I do a LIST
, the response ends with a .
. But in SMT开发者_运维问答P, when I do a EHLO
, it doesn't give clear indication of when the response has ended.
The use of in.read() == -1
, sadly, doesn't work as it will still attempt to read beyond the responded data and causes the socket to hang.
So, how do I determine the end of a SMTP and POP response? Better still, is it even possible to know before hand how many bytes I should read from the buffer so that I won't even have to check for end of response?
The 2 protocols are different but both are sending messages that end with a newline. With SMTP, you read 1 line at a time (ending with \n), each line you read should start with 3 numbers, then either a space or a '-', if it's a space, then that's the end of the server's response, if it's a '-' (like 250-VRFY
which is what you'd get if you opened up with an EHLO, prompting the server to respond with a list of extended ESMTP commands) then you need to read another line.
With POP3, I believe it depends on the command that you issue. Something like USER or PASS gives you a '+' or '-' response (followed by a code and some text). A command like LIST gives you a '+' or '-', and if '+', you get your list of emails, which will end with a single '.' by itself. Each of these responses (as well as each index of an email) will be a line.
You should take a look at RFC 821 for SMTP and RFC 1939 for POP3 to get a detailed description of the protocols
In SMTP the end of a response from the server side of the transaction can be determined by looking at the character after the response code: it's a '-' after the status code on every line of the response except for the last line--
Client: EHLO my.mailserver.com
Server: 123-This is a
Server: 123 Multi-line response
So, for SMTP (I haven't dealt with POP before but it sounds like you've worked that one out!), you'll need to check for the presence of this '-' character after the status code to determine if there are more lines in the response.
The current SMTP RFC (5321) documents this: https://www.rfc-editor.org/rfc/rfc5321 (e.g. page 32)
精彩评论