Socket Problem: Client connects to a server that does not exit!

R

Ramon

Hi,

I'm writing a simple client that connects to a server. Code:
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 60000);

I was testing the client. One test was to "switch off" the server that
was running on the localhost on port 60000. For some reason, the client
still manages to connect to the server. I tried to telnet that port, to
make sure that there is not program running.

My questions are:
[1] What am I doing wrong?
[2] Is this a bug?

From java.sun.com:
public Socket(InetAddress address, int port)
throws IOException
Creates a stream socket and *connects* it to the specified port number
at the specified IP address.

Thanks
 
K

Knute Johnson

Ramon said:
Hi,

I'm writing a simple client that connects to a server. Code:
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 60000);

I was testing the client. One test was to "switch off" the server that
was running on the localhost on port 60000. For some reason, the client
still manages to connect to the server. I tried to telnet that port, to
make sure that there is not program running.

My questions are:
[1] What am I doing wrong?
[2] Is this a bug?

From java.sun.com:
public Socket(InetAddress address, int port)
throws IOException
Creates a stream socket and *connects* it to the specified port number
at the specified IP address.

Thanks

You might do a netstat to see if there is in fact something listening on
that port. What happens when you telnet to it?
 
E

EJP

Ramon said:
I was testing the client. One test was to "switch off" the server that
was running on the localhost on port 60000. For some reason, the client
still manages to connect to the server.

Connections to 'localhost' seem to always succeed, and then fail at the
first read or write if the port wasn't listening. This isn't Java, I
first observed this behaviour about 1992. In one library I wrote I tried
a zero-length write immediately after the connect() call to detect this
case. Not sure if that would work in Java because I don't know that the
write would get all the way down to the silicon.
 
R

Ramon

Knute said:
You might do a netstat to see if there is in fact something listening on
that port.
Yes I did netstat and no service was running on port 60000
What happens when you telnet to it?

D:\Documents and Settings\ramon>telnet localhost 60000
Connecting To localhost...Could not open connection to the host, on port
60000:
Connect failed

No server is running on port 60000.
 
R

Ramon

EJP said:
Connections to 'localhost' seem to always succeed,
Glad that someone else has noticed this.
and then fail at the first read or write if the port wasn't listening.
The server's aim is to allow clients downloading an image. When the
server is not running, the clients, strangely enough, still manage to
connect to server PLUS create an empty image (jpeg) file (i.e. it does
not fail at the first read/write).

Here is my client's code. Am I doing something wrong?

/*
* CLIENT'S CODE:
*/
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 60000);

InputStream inputStream = s.getInputStream();
OutputStream outputStream = new FileOutputStream(path + "/downloaded.jpeg");

byte[] buffer = new byte[1024];
while ( inputStream.read(buffer) > 0 )
outputStream.write(buffer);

// closing stuff ...etc.
 
N

Nigel Wade

Ramon said:
Glad that someone else has noticed this.

The server's aim is to allow clients downloading an image. When the
server is not running, the clients, strangely enough, still manage to
connect to server PLUS create an empty image (jpeg) file (i.e. it does
not fail at the first read/write).

In the code below you create the output file before you attempt to read from the
input stream. So that fact doesn't demonstrate that it isn't failing on the
first read attempt.
Here is my client's code. Am I doing something wrong?

I get

Java.net.ConnectionException: Connection refused

thrown at the Socket creation line. Which is exactly what I would expect to
happen. This is on both Linux and Windows (XP).

Matt's suggestion makes a lot of sense. Something has to be taking the initial
SYN packet and replying with a SYN/ACK rather than RST/ACK on that port for the
Socket to be created. Maybe your firewall is a tar-pit, accepting the SYN
replying with SYN/ACK and then doing nothing, to deliberately impeded port
scanners.
 
L

Lew

Matt said:
Ramon said:
EJP said:
Connections to 'localhost' seem to always succeed,
Glad that someone else has noticed this.
and then fail at the first read or write if the port wasn't listening.
The server's aim is to allow clients downloading an image. When the
server is not running, the clients, strangely enough, still manage to
connect to server PLUS create an empty image (jpeg) file (i.e. it does not
fail at the first read/write).

Here is my client's code. Am I doing something wrong?

/*
* CLIENT'S CODE:
*/
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 60000);

InputStream inputStream = s.getInputStream();
OutputStream outputStream = new FileOutputStream(path +
"/downloaded.jpeg");

byte[] buffer = new byte[1024];
while ( inputStream.read(buffer) > 0 )
outputStream.write(buffer);

Don't presume that inputStream.read will fill the whole buffer. If it only
reads n bytes, you will still write 1024 and thereby put garbage into your
output file.

int r;
while ((r = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, r);
}

Don't use '> 0' for the test. That risks prematurely ending the read loop.
Use '>= 0'.
public int read(byte[] b) ....
Returns:
the total number of bytes read into the buffer,
or -1 is there is no more data
because the end of the stream has been reached.
<http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#read(byte[])>
 
K

Knute Johnson

Lew said:
Matt said:
Ramon said:
EJP wrote:
Connections to 'localhost' seem to always succeed,
Glad that someone else has noticed this.

and then fail at the first read or write if the port wasn't listening.
The server's aim is to allow clients downloading an image. When the
server is not running, the clients, strangely enough, still manage to
connect to server PLUS create an empty image (jpeg) file (i.e. it
does not fail at the first read/write).

Here is my client's code. Am I doing something wrong?

/*
* CLIENT'S CODE:
*/
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 60000);

InputStream inputStream = s.getInputStream();
OutputStream outputStream = new FileOutputStream(path +
"/downloaded.jpeg");

byte[] buffer = new byte[1024];
while ( inputStream.read(buffer) > 0 )
outputStream.write(buffer);

Don't presume that inputStream.read will fill the whole buffer. If it
only reads n bytes, you will still write 1024 and thereby put garbage
into your output file.

int r;
while ((r = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, r);
}

Don't use '> 0' for the test. That risks prematurely ending the read
loop. Use '>= 0'.
public int read(byte[] b) ...
Returns:
the total number of bytes read into the buffer, or -1 is there is
no more data because the end of the stream has been reached.
<http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#read(byte[])>

I always use while != -1. Just seemed to be more readable to me.
 
L

Lew

Knute said:
Lew said:
Matt said:
EJP wrote:
Connections to 'localhost' seem to always succeed,
Glad that someone else has noticed this.

and then fail at the first read or write if the port wasn't listening.
The server's aim is to allow clients downloading an image. When the
server is not running, the clients, strangely enough, still manage
to connect to server PLUS create an empty image (jpeg) file (i.e. it
does not fail at the first read/write).

Here is my client's code. Am I doing something wrong?

/*
* CLIENT'S CODE:
*/
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 60000);

InputStream inputStream = s.getInputStream();
OutputStream outputStream = new FileOutputStream(path +
"/downloaded.jpeg");

byte[] buffer = new byte[1024];
while ( inputStream.read(buffer) > 0 )
outputStream.write(buffer);

Don't presume that inputStream.read will fill the whole buffer. If
it only reads n bytes, you will still write 1024 and thereby put
garbage into your output file.

int r;
while ((r = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, r);
}

Don't use '> 0' for the test. That risks prematurely ending the read
loop. Use '>= 0'.
public int read(byte[] b) ...
Returns:
the total number of bytes read into the buffer, or -1 is there is
no more data because the end of the stream has been reached.
<http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#read(byte[])>

I always use while != -1. Just seemed to be more readable to me.

I like a for() loop.
 
L

Lew

Peter said:
[...]
byte[] buffer = new byte[1024];
while ( inputStream.read(buffer) > 0 )
outputStream.write(buffer);

Don't presume that inputStream.read will fill the whole buffer. If
it only reads n bytes, you will still write 1024 and thereby put
garbage into your output file.
int r;
while ((r = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, r);
}

Don't use '> 0' for the test. That risks prematurely ending the read
loop. Use '>= 0'.

I'm a bit confused. Why would there be a risk of prematurely ending the
read loop?

According to the docs, the only time you'd get a return value of 0 is if
you pass a 0-length buffer to the method in the first place. That's not
the case here, and so the return value should either be -1 (for
end-of-stream) or some value larger than 0.

Code that tries to read 0 bytes should be unusual in any case, and as
long as more than 0 bytes are attempted to be read, you shouldn't get 0
as a return value from the read() method, based on my reading of the docs.

I suppose one could debate the theoretical correctness of "> 0" versus
">= 0", and this being Usenet surely that will happen. But in terms of
whether the program will ever produce incorrect output using one versus
the other, I believe there's no difference between the two.

Good point.
 
K

Knute Johnson

Lew said:
Knute said:
Lew said:
Matt Humphrey wrote:
EJP wrote:
Connections to 'localhost' seem to always succeed,
Glad that someone else has noticed this.

and then fail at the first read or write if the port wasn't
listening.
The server's aim is to allow clients downloading an image. When
the server is not running, the clients, strangely enough, still
manage to connect to server PLUS create an empty image (jpeg) file
(i.e. it does not fail at the first read/write).

Here is my client's code. Am I doing something wrong?

/*
* CLIENT'S CODE:
*/
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 60000);

InputStream inputStream = s.getInputStream();
OutputStream outputStream = new FileOutputStream(path +
"/downloaded.jpeg");

byte[] buffer = new byte[1024];
while ( inputStream.read(buffer) > 0 )
outputStream.write(buffer);

Don't presume that inputStream.read will fill the whole buffer. If
it only reads n bytes, you will still write 1024 and thereby put
garbage into your output file.

int r;
while ((r = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, r);
}

Don't use '> 0' for the test. That risks prematurely ending the read
loop. Use '>= 0'.

public int read(byte[] b)
...
Returns:
the total number of bytes read into the buffer, or -1 is there
is no more data because the end of the stream has been reached.
<http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#read(byte[])>

I always use while != -1. Just seemed to be more readable to me.

I like a for() loop.

It's a great world isn't it?
 
E

EJP

Matt said:
Good catch!

No, it's a *particularly bad* catch. As has been discussed here, the
only way read() can return 0 is if the buffer is zero length. The reason
it's a poor practice is that if the buffer length happens to be zero,
the last thing you should do is put the application into a hard spin loop.
 
R

Ramon

Peter said:
Since you get the successful connection, your code goes ahead and does
the stream stuff, including creating a new FileOutputStream instance.
That, of course, will create an empty file. Which appears to be what
you're asking about, right?
My question was how is it possible for a client to connect (using new
Socket(addr, port)) to a localhost service if that service does not exists?

Some people suggested that I might have a "smart" firewall... but my
firewall is switched off. The only firewall that I have is that of the
router, which I assume will not affect the result since I am trying to
connect to localhost.

The O/S that I am using is Win Xp sp3 -- I will later test my program on
Linux and UNIX. The javac's version is 1.6.0.

Is this a Java compiler's bug? EJP experienced the same problem.
You can either not actually create the FileOutputStream instance until
you've actually got data to write to it, or you can include some
error-detection (like having a zero-length stream) and delete the file
after the fact when an error occurs.

Which is best depends on what your users need. If you need for your
users to only ever have valid, fully-downloaded files, deleting the file
might the best approach. On the other hand, if you have users that will
want partial data (for whatever reason) even if an error occurs, it's
probably better to simply delay creation of the file until you've
actually gotten one or more bytes out of your stream.

Of course, if partial data is okay, then perhaps an empty file is okay
too, in which case you can simply ignore the entire problem as a
non-issue. :)

Good point. Thanks pete!
 
L

Lothar Kimmeringer

Ramon said:
I was testing the client. One test was to "switch off" the server that
was running on the localhost on port 60000. For some reason, the client
still manages to connect to the server. I tried to telnet that port, to
make sure that there is not program running.

I had the same problem with Windows Vista and IPV6. Windows
itself was taking over the ServerSocket until the Javaprocess
was finished. Until that a telnet-connection was possible
and I got a "Willkommen" as response-text. Just letting the
server listen to IPV4 solved that problem temporarily. I'm not
sure if that is the same effect you experienced
(getByName(127.0.0.1) might return an IPV6-address) but you
can try letting the server bind its ServerSocket to IPV4.


Regards, Lothar
--
Lothar Kimmeringer E-Mail: (e-mail address removed)
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!
 
N

Nigel Wade

Ramon said:
My question was how is it possible for a client to connect (using new
Socket(addr, port)) to a localhost service if that service does not exists?

Some people suggested that I might have a "smart" firewall... but my
firewall is switched off. The only firewall that I have is that of the
router, which I assume will not affect the result since I am trying to
connect to localhost.

That makes it a whole lot more interesting. /Something/ must be accepting that
initial SYN packet. If nothing is listening TCP should reply with SYN/RST. This
should result in an IOException.
The O/S that I am using is Win Xp sp3 -- I will later test my program on
Linux and UNIX. The javac's version is 1.6.0.

I tried it on Linux and XP/SP3 with Java 1.6.0 and got the expected IOException.
Is this a Java compiler's bug?

Unlikely. I think something at a much lower level is telling Java that the
connection has been established. It is possible it's a bug in Java which is
being triggered by something else, but it would be very difficult to pin down.
Does this always happen, even after a re-boot? Just wondering if there might be
a lingering connection in some intermediate shutdown state which is resulting
in the error. It shouldn't happen, TCP is supposed to handle this, but it is a
Microsoft OS and they don't have the best reputation/track-record at
implementing "standards" over which they don't have total control.
EJP experienced the same problem.

I remain to be convinced it's the same problem.
 
E

EJP

Ramon said:
My question was how is it possible for a client to connect (using new
Socket(addr, port)) to a localhost service if that service does not exists?

Some people suggested that I might have a "smart" firewall... but my
firewall is switched off. The only firewall that I have is that of the
router, which I assume will not affect the result since I am trying to
connect to localhost.

The O/S that I am using is Win Xp sp3 -- I will later test my program on
Linux and UNIX. The javac's version is 1.6.0.

Is this a Java compiler's bug? EJP experienced the same problem.

Pardon me. What I said was 'This isn't Java, I first observed this
behaviour about 1992'.

In fact it was C++, and I was using many platforms including Windows
3.1, OS/2, Netware 3.x, BSD Unix, SC Unix, MS.DOS, etc etc. I don't say
that all those platforms exhibited the problem but enough did that I had
to introduce code to defend against it. So that would indicate it's a
TCP stack bug.

Certainly nothing to do with Java. And BTW I haven't seen that behaviour
since.
 
R

Ramon

I've tested the client program on Linux and it worked perfectly
(compiler version 1.6.0_07) -- i.e. when there was no server running on
port 60000, the client had thrown java.net.ConnectException.

It means that either:
[1] There is a bug in Windows (for a change :))
[2] or my Windows javac is "corrupted"
[3] or, as some of you has pointed out, their might be some sort of
program running in the background...etc.

I'll try to upgrade the javac and if the problem persists, I'll try to
monitor the connection.
 
E

EJP

Ramon said:
[2] or my Windows javac is "corrupted"

It *certainly* has nothing to do with javac. That's the compiler and the
compiler knows diddly-squat about sockets. It *might* have something to
do with your rt.jar, but it doesn't. It's not a Java issue. If it was,
*all* connections would succeed to any host: unless you're suggesting
there's sockets code in rt.jar that behaves differently for 'localhost',
which there isn't.

It is clearly a platform issue.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top