Java сокеты зависает при чтении всего вывода - PullRequest
2 голосов
/ 15 февраля 2012

У меня есть сокет в Java, который подключается к SMTP-серверу для отправки электронной почты и использует BufferedReader и Writer для чтения и записи в сокет. Моя проблема в том, чтобы знать, когда завершить цикл while(), вызываемый после записи в сокет; используя

while(bufferedreader.readLine() != null)

не работает, как будто нет строки для чтения с сервера, BufferedReader просто зависает вместо возврата null.

Ответы [ 4 ]

2 голосов
/ 15 февраля 2012

Не используйте readLine() при чтении данных из сокетов, поскольку readLine() предполагает, что входящий поток является текстовым файлом с окончанием строки.Возможно, это не тот случай, который блокировал бы readLine() на неопределенный срок, потому что нет окончания строки, даже если входящий поток закончился.

0 голосов
/ 15 февраля 2012

Я очень рекомендую не изобретать велосипед и использовать SMTPClient из Apache Commons Net проект.

Если вы не занимаетесь исследовательской / образовательной работой.

0 голосов
/ 15 февраля 2012

Вы не должны использовать "while (bufferedreader.readLine ()! = Null)", потому что он читает каждую строку из сокета и зависает до тех пор, пока не будет опубликовано что-то новое.

Это не будет работать, за исключением команды «QUIT», потому что для других этапов диалога с SMTP-сервером вам нужно прочитать только несколько строк, а затем отправить другую команду и т. Д., И т. Д. .

В зависимости от типа команды smtp, вы будете ожидать разные ответы. Вы должны внимательно прочитать SMTP RFC (база в 2821 - http://www.ietf.org/rfc/rfc2821.txt), чтобы понять базовый протокол.

Как правило, большая часть команды, которую вы отправите, получит однострочный ответ с кодом результата. Этот код указывает, что делать (читать больше строк или перейти к следующей команде).

Пример: отправив 'HELO myserver', вы ожидаете ответа '250 xxx' (или это сбой!).

Итак, вы просто прочитали 1 строку.

Отправляя 'EHLO myserver', вы ожидаете больше строк, не помните условие остановки.

и т. Д., Т.

Например, на моем локальном EXIM у меня есть такие результаты:

Сначала прочитайте 1 строку с сервера, проверьте 220

220 jm.localdomain ESMTP Exim 4.72 Wed, 15 Feb 2012 13:52:36 +0100

Затем отправьте:

HELO localhost

прочитайте и проверьте 250:

250 jm.localdomain Hello me [127.0.0.1]

и т. Д.

MAIL FROM: me@yahoo.com
250 OK
RCPT TO: everybody@yahoo.com
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
Subject: how are you?

bla
bla
bla
.
250 OK id=1RxePi-00074k-Nv
QUIT
221 jm.localdomain closing connection
0 голосов
/ 15 февраля 2012

Вам необходимо проанализировать SMTP сообщений из потока, чтобы выяснить, когда остановиться. Например, вам нужно отправить сообщение QUIT на сервер, чтобы указать, что вы закончили, а затем перехватить 221 Bye.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...