Socket read fails but write is successful. Why?

Hi once more!

I have a Java application, reading and writing from/to a client socket:

...

InputStream is = socket.getInputStream();

BufferedReader br =new BufferedReader(new InputStreamReader(is));

...

i = br.read();

...

If i is equal to -1, it means there's no connection or that somehow the connection is unavailable right? So, how come is it possible to write to the socket's output stream with success after that read( ) returning -1? Shouldn't it also fail?

I'm trying a "persistent" TCP connection, so I use that condition (read () == -1) to determine when the connection is down (read() is only blocking a certain amount of time).

Thanks!

[784 byte] By [pcsantosa] at [2007-11-26 15:09:48]
# 1

> If i is equal to -1, it means there's no

> connection or that somehow the connection is

> unavailable right?

Wrong. It means the peer has closed its end, or shut it down for output.

> So, how come is it possible to

> write to the socket's output stream with success

> after that read( ) returning -1? Shouldn't it also

> fail?

That would suggest that the peer has called shutdownOutput() but still has the read side of the socket open. In this state you can still write to your socket.

> I'm trying a "persistent" TCP connection, so I use

> that condition (read () == -1) to determine when the

> connection is down (read() is only blocking a certain

> amount of time).

See above. Read returning -1 doesn't mean 'down', it means 'finished'. A read timeout might mean 'down' depending on the timer value and the nature of what's at the other end.

ejpa at 2007-7-8 9:00:31 > top of Java-index,Core,Core APIs...
# 2

Thanks for your tips once again..

So, if you're trying to manage a persistent TCP connection using a socket application, how would you detect connection failure? Like I said, I was using read ( ) and write ( ) together to detect this, but it doesn't seem to be working out properly.

I just disabled network connection and the application kept running normaly.. listenning and sending as if it was connected. How can it be? If I start my app after network being disabled, the app detects there's no connection. But, if it's already running.. it keeps running without errors. Shouldn't read ( ) and / or write ( ) fail here? There's no connection!

These socket issues have surely become a hard challenge to me... I can't seem to make this work without flaws. Your help is greatly appreciated! Thanks

pcsantosa at 2007-7-8 9:00:31 > top of Java-index,Core,Core APIs...
# 3

I've been reading some other thread after posting and got some ideas on "connection failure".

Would you trust just the write method to test if there's connection to the server? But, what if it's not able to read like I stated on my first post (after restarting application read ( ) worked fine.. without returning -1). Besides.. read is more accurate in detecting failures. I only write once per minute, so read is much more frequent.

pcsantosa at 2007-7-8 9:00:31 > top of Java-index,Core,Core APIs...
# 4

> Would you trust just the write method to test if

> there's connection to the server?

Well that's not really what happens. There is really no such thing as a 'connection' in the sense of a telephone with a dial tone you can listen to. We are in packet-switching land and the 'existence of a connection' doesn't mean anything more than the ability to send the next packet. Which is a prediction of the future.

What write does is cause packets to be sent which require acknowledgement, and if the ACKs don't arrive, eventually a subsequent write() will fail. A read doesn't engage in any wire protocol at all, which is why it can't be used to detect a connection failure other than via a read timeout, or as a result of prior writes.

ejpa at 2007-7-8 9:00:31 > top of Java-index,Core,Core APIs...
# 5

Referring to the perfect definition that ejp gives for 'existence of connection': doesn't mean anything more than the ability to send the next packet. Which is a prediction of the future.

What you want to check is that you have the ability to send a packet. Have you tried the methods from the Socket class isBound(), isClosed(), isConnected() or probably the most suitable for your case: isOutputShutdown()?

If they all return true when you disconnect the cable, I suggest you to have a process constantly sending a byte just to check that you still have the ability to send a packet

jjilko@hotmail.coma at 2007-7-8 9:00:31 > top of Java-index,Core,Core APIs...
# 6

> What you want to check is that you have the ability

> to send a packet. Have you tried the methods from the

> Socket class isBound(), isClosed(), isConnected() or

> probably the most suitable for your case:

> isOutputShutdown()?

It obviously follows from the 'perfect definition' that these methods can't tell you anything about the state of the connection, because there is no 'state of the connection' to inspect, because there is no connection in the first place. As I said above. You should have seen that immediately.

All these methods do is tell you whether you have called the corresponding bind/connect/close/shutdown/... method on this socket at this end of the connection.

> If they all return true when you disconnect the cable

Disconnecting the cable won't make the slightest difference to what they return. How could it?

> I suggest you to have a process constantly

> sending a byte just to check that you still have the

> ability to send a packet

Now you've got it.

ejpa at 2007-7-8 9:00:31 > top of Java-index,Core,Core APIs...
# 7

> > I suggest you to have a process constantly

> > sending a byte just to check that you still have

> > the ability to send a packet

>

> Now you've got it.

That's what I'm doing, yet I feel in my case it's not enough.

I communicate with the server asynchronously. I send packets.. somewhen the server sends packets to my client.

This way, I have to be continuously reading from the socket's Input Stream, in order to check for incoming packets (which may arrive at any time)... Thus, I have to be sure I can read from the socket..

As the connection may timeout (if neither my client nor the server write anything to the socket) I send a dummy packet once per minute.

However:

1) This is too long to check connection status (only 1 time each minute)

2) It doesn't tell me I can read ok from the socket - check the case where I could write but read ( ) returned -1. This is abnormal behaviour in my case.. do you think if the server was sending some packets, my read ( ) would be able to capture them (even after returning -1 for quite a while)? It seemed to me I was able to send, yet unable to receive.. or my packets weren't actually reaching the server even though they seemed to be.

> What write does is cause packets to be sent which

> require acknowledgement, and if the ACKs don't

> arrive, eventually a subsequent write() will fail. A

> read doesn't engage in any wire protocol at all,

> which is why it can't be used to detect a connection

> failure other than via a read timeout, or as a result

> of prior writes.

Why does write ( ) doesn't fail when I unplug the cable? Either way this situation isn't quite important, as long as my packets start actually reaching the server after the cable is plugged back in. Curious, however, how write ( ) doesn't fail..

pcsantosa at 2007-7-8 9:00:31 > top of Java-index,Core,Core APIs...