Thread View: comp.lang.java.programmer
6 messages
6 total messages
Started by Rosinger
Mon, 11 Feb 2002 12:07
Problems with blocking socket
Author: Rosinger
Date: Mon, 11 Feb 2002 12:07
Date: Mon, 11 Feb 2002 12:07
68 lines
3109 bytes
3109 bytes
Hi all,
I am experimenting with sockets in Java. I have this little program that
I've written:
------------------------------------------------------------------------
import java.net.*;
import java.io.*;
public class client
{
public static void main (String[] args) throws IOException
{
String username = "foo";
String password = "bar";
Socket socket = new Socket ("mail", 110); // mail is my local POP3 server
BufferedReader in = new BufferedReader (new InputStreamReader
(socket.getInputStream()));
PrintWriter out = new PrintWriter (new OutputStreamWriter
(socket.getOutputStream()));
// send command to server
out.print (username + "\n");
out.flush();
// read response
String response = "";
String line;
while ((line = in.readLine()) != null)
{
response += line;
}
System.out.println (response);
in.close();
out.close();
socket.close();
}
}
------------------------------------------------------------------------
Nothing too complicated, but there is a little problem: the while loop
keeps blocking and does NOT return null when there's nothing to read
from the socket.
If, for example, I replace the host to "www" (my local web server) and
request to get an HTML file like:
out.print ("GET " + "/index.html" + " HTTP/1.0\n\n")
out.flush();
The while loop gets back the HTML file line by line, and when the entire
file has been read, it does NOT block anymore.
I find it very strange that for the mail server example, the while loop
does NOT return null when there's nothing to read from the socket and
keeps blocking, while the web server example DOES return null and
returns when there's nothing to read from the socket.
Does anyone know what the difference between the mail server and the web
server is? Or, how to solve this problem?
Thanks in advance,
Cheers,
Joshua
Re: Problems with blocking socket
Author: Jon Skeet
Date: Mon, 11 Feb 2002 12:45
Date: Mon, 11 Feb 2002 12:45
51 lines
2872 bytes
2872 bytes
Rosinger <rosinger@optushome.com.au> wrote:
> String response = "";
> String line;
> while ((line = in.readLine()) != null)
> {
> response += line;
> }
This bit of code is horrible, by the way - use a StringBuffer.
See http://www.pobox.com/~skeet/java/string.html
> System.out.println (response);
>
> in.close();
> out.close();
> socket.close();
> }
> }
These close calls should be part of a finally block, so they get
executed even if an IO exception is thrown.
Neither of these are major problems for small test code, but I thought
I'd just raise them in case you weren't aware of them.
> Nothing too complicated, but there is a little problem: the while loop
> keeps blocking and does NOT return null when there's nothing to read
> from the socket.
Indeed - and that's correct. It should only return null when the socket
has been closed (by either end).
> I find it very strange that for the mail server example, the while loop
> does NOT return null when there's nothing to read from the socket and
> keeps blocking, while the web server example DOES return null and
> returns when there's nothing to read from the socket.
Nope, the web server is closing the socket in this case, hence the
return of null.
> Does anyone know what the difference between the mail server and the web
> server is? Or, how to solve this problem?
In a mail server, the protocol should tell you how much to read - eg by
finishing with a line of just "." - but this depends on the protocol you
want to use.
--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Re: Problems with blocking socket
Author: Gordon Beaton
Date: Mon, 11 Feb 2002 12:49
Date: Mon, 11 Feb 2002 12:49
51 lines
2757 bytes
2757 bytes
On Mon, 11 Feb 2002 23:07:34 +1100, Rosinger wrote:
> I am experimenting with sockets in Java. I have this little program
> that I've written:
[...]
> while ((line = in.readLine()) != null)
> {
> response += line;
> }
> Nothing too complicated, but there is a little problem: the while
> loop keeps blocking and does NOT return null when there's nothing to
> read from the socket.
It is behaving exactly as it should.
> Does anyone know what the difference between the mail server and the
> web server is? Or, how to solve this problem?
BufferedReader.readLine() returns null at EOF. That means that the end
of the stream has been reached, that there will *never* be any more
data available. Not that there is nothing to read "for the moment".
As long as the connection is still active, readLine() will block until
a complete line has been received, at which point it will be returned
to the caller.
When you tested with a web server, it sent you the file and closed the
connection, so EOF was reached and readLine() returned null.
When you tested with a mail server, the remote did not close the
connection because the session is not yet over; it is waiting for
additional commands. You would have run into the same problem if you
had specified HTTP/1.1 when you connected to the web server.
You need to use different criteria for determining when the end of the
data has been reached. For example the pop server might tell you the
length of the mail before transferring it, and there may be a prompt
that appears afterwards.
You should read the protocol definitions so you can deal with this
situation properly:
pop: http://www.ietf.org/rfc/rfc1939.txt
http: http://www.ietf.org/rfc/rfc2616.txt
/gordon
--
[ do not send me private copies of your followups ]
g o r d o n . b e a t o n @ e r i c s s o n . c o m
Re: Problems with blocking socket
Author: Manish Jethani
Date: Mon, 11 Feb 2002 14:37
Date: Mon, 11 Feb 2002 14:37
18 lines
1515 bytes
1515 bytes
Rosinger wrote:
> out.print (username + "\n");
If you really want to auth, it should be:
out.print("USER " + username
+ "\r\n"); /* end with \r\n */
> while ((line = in.readLine()) != null)
The USER command of pop3 will return just a single line. And
the connection does not get closed (unlike in HTTP), so you
should read just one line and don't wait for EOF
(readLine() == null).
Check the POP3 rfc - http://www.ietf.org/rfc/rfc1939.txt .
Manish
Re: Problems with blocking socket
Author: Timo Kinnunen
Date: Mon, 11 Feb 2002 15:45
Date: Mon, 11 Feb 2002 15:45
56 lines
2513 bytes
2513 bytes
Jon Skeet <skeet@pobox.com> wrote:
> Rosinger <rosinger@optushome.com.au> wrote:
>> System.out.println (response);
>>
>> in.close();
>> out.close();
>> socket.close();
>> }
>> }
>
> These close calls should be part of a finally block, so they get
> executed even if an IO exception is thrown.
What is the best way to close multiple streams? This ofcourse depends
on whether the method has been declared to throw an IOException. I've
considered a lot of different approaches, but I haven't found a winner
yet. Some of the better:
Doesn't throw an IOException:
try {
// ...
} finally {
closeIfNonNullAndIgnoreIOException(in);
closeIfNonNullAndIgnoreIOException(out);
closeIfNonNullAndIgnoreIOException(socket);
}
Throws an IOException:
try {
// ...
} catch(IOException e) {
closeIfNonNullAndIgnoreIOException(in);
in = null;
closeIfNonNullAndIgnoreIOException(out);
out = null;
closeIfNonNullAndIgnoreIOException(socket);
socket = null;
throw e;
} finally {
try {
if(in != null) in.close();
} finally {
try {
if(out != null) out.close();
} finally {
if(socket != null) socket.close();
}
}
}
--
No address munging in use. I like the smell of nuked accounts in the
morning.
Re: Problems with blocking socket
Author: Jon Skeet
Date: Mon, 11 Feb 2002 17:16
Date: Mon, 11 Feb 2002 17:16
37 lines
2428 bytes
2428 bytes
Timo Kinnunen <timo.kinnunen@bigfoot.com> wrote:
> Jon Skeet <skeet@pobox.com> wrote:
>
> > Rosinger <rosinger@optushome.com.au> wrote:
> >> System.out.println (response);
> >>
> >> in.close();
> >> out.close();
> >> socket.close();
> >> }
> >> }
> >
> > These close calls should be part of a finally block, so they get
> > executed even if an IO exception is thrown.
>
> What is the best way to close multiple streams? This ofcourse depends
> on whether the method has been declared to throw an IOException. I've
> considered a lot of different approaches, but I haven't found a winner
> yet. Some of the better:
>
> Doesn't throw an IOException:
>
> try {
> // ...
> } finally {
> closeIfNonNullAndIgnoreIOException(in);
> closeIfNonNullAndIgnoreIOException(out);
> closeIfNonNullAndIgnoreIOException(socket);
> }
That's the kind of thing I normally use - IOUtil.close in my case. I
normally make it log any throwables caught, basically.
--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads