Yawn
Yawn

Reputation: 519

Java sockets hangs when reading all output

I have a socket in Java that connects to an SMTP server to send email and uses a BufferedReader and a Writer to read and write to the socket. My problem is knowing when to terminate the while() loop called after writing to the socket; using

while(bufferedreader.readLine() != null)

doesn't work as if there isn't a line to read from the server the BufferedReader just hangs instead of returning null.

Upvotes: 2

Views: 583

Answers (4)

mre
mre

Reputation: 44240

Do not use readLine() when reading data from sockets since readLine() assumes that the incoming stream is a text file, which has line endings. This might not be the case, which would block the readLine() indefinitely because there's no line ending coming even though the incoming stream has ended.

Upvotes: 2

huelbois
huelbois

Reputation: 7012

You musn't use "while(bufferedreader.readLine() != null)" because what it does is read every line from the socket, and hang until something new is posted.

It won't work, except for the "QUIT" command, because for the other phases of the dialogue with the SMTP server, you need to read only a few of the lines, and then send another command, etc, etc.

Depending on the type of smtp command you run, you will expect different answers. You have to read carefully the SMTP RFC (base in 2821 - http://www.ietf.org/rfc/rfc2821.txt) to understand the underlying protocol.

Basically, most of the command you will send will receive a one-line answer with a result code . This code indicates what to do (read more lines, or skip to the next command).

Ex: by sending 'HELO myserver', you will expect a '250 xxx' answer (or it's a failure !).

So you just read 1 line.

By sending 'EHLO myserver', you will expect more lines, don't remember the stop condition.

etc, etc, etc...

For example, on my local EXIM I have those results:

First, read 1 line from the server, check 220

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

Then send:

HELO localhost

read and check 250 :

250 jm.localdomain Hello me [127.0.0.1]

and so on

MAIL FROM: [email protected]
250 OK
RCPT TO: [email protected]
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

Upvotes: 0

Oleg Mikheev
Oleg Mikheev

Reputation: 17444

I would highly recommend not to reinvent the wheel and to use SMTPClient from Apache Commons Net project.

Unless you're doing some research/educational work.

Upvotes: 0

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84169

You need to parse SMTP messages out of the stream to figure out when to stop. For example, you need to send a QUIT message to the server to indicate that you are done and then catch the 221 Bye.

Upvotes: 0

Related Questions