Как определить конец ответа SMTP и POP? - PullRequest
2 голосов
/ 15 октября 2011

Я читаю символ за символом ответа сокета в BufferedReader, записанном из сокета, который я подключаю к SMTP и POP-серверу. Но как мне узнать, прочитал ли я до конца ответа, чтобы избежать зависания read() для чтения сверх того, что ответил сервер? Следующий код показывает, как я читаю из 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;
    }
}

Например, в POP, когда я делаю LIST, ответ заканчивается .. Но в SMTP, когда я делаю EHLO, он не дает четкого указания, когда закончился ответ.

Использование in.read() == -1, к сожалению, не работает, так как оно все равно будет пытаться прочитать данные, оставшиеся без ответа, и приведет к зависанию сокета.

Итак, как мне определить окончание ответа SMTP и POP? Более того, возможно ли даже узнать заранее, сколько байтов я должен прочитать из буфера, чтобы мне даже не пришлось проверять конец ответа?

Ответы [ 2 ]

9 голосов
/ 15 октября 2011

2 протокола разные, но оба отправляют сообщения, заканчивающиеся символом новой строки.При использовании SMTP вы читаете по 1 строке за раз (заканчивается на \ n), каждая прочитанная строка должна начинаться с 3 цифр, затем либо с пробела, либо с «-», если это пробел, то это конец ответа сервера, если это «-» (например, 250-VRFY, то есть то, что вы получите, если откроете EHLO, запрашивающий у сервера ответ со списком расширенных команд ESMTP), тогда вам нужно прочитать еще одну строку.

Я полагаю, что с POP3 это зависит от команды, которую вы вводите.Что-то вроде USER или PASS дает вам ответ «+» или «-» (за которым следует код и текст).Такая команда, как LIST, дает вам «+» или «-», а если «+», вы получаете список электронных писем, который заканчивается единственным «.»само собой.Каждый из этих ответов (а также каждый индекс электронного письма) будет представлять собой строку.

Вам следует взглянуть на RFC 821 для SMTP и RFC 1939 для POP3 , чтобы получить подробное описание протоколов

4 голосов
/ 15 октября 2011

В SMTP конец ответа со стороны сервера транзакции можно определить, посмотрев на символ после кода ответа: это «-» после кода состояния в каждой строке ответа, кроме последней строки -

Client: EHLO my.mailserver.com
Server: 123-This is a
Server: 123 Multi-line response

Итак, для SMTP (я раньше не имел дело с POP, но, похоже, вы уже с этим поработали!), Вам необходимо проверить наличие этого символа «-» после кода состояния, чтобы определить, есть ли еще строки в ответе.

Текущий SMTP RFC (5321) документирует это: http://tools.ietf.org/html/rfc5321 (например, стр. 32)

...