sockets: output flush causes input read to not block

Hi,

My requirement is to write a server that is capable of holding long conversations with the client based on socket programming for Java. I'm using ServerSocket to create TCP sockets. The problem I am running into is that I am not able to do [read, write, read] sequence of operations reliably on my socket. Here is my [read, write, read] code:

1: int numBytesRead = socket.getInputStream().read(buffer);

2: System.out.println(numBytesRead);

3: socket.getOutputStream().write(new byte[] { 'a', 'b', 'c' });

4: socket.getOutputStream().flush();

5: numBytesRead = socket.getInputStream().read(buffer);

6: System.out.println(numBytesRead);

On line 5 in this code, the read operation is NOT blocking and will return -1. After some testing, I concluded that after flushing output [line 4], the input stream will not block anymore. However, if I comment out line 4, the read operation will block again, and will continue to block on subsequent attempts for read before any output flush. What I want is to implement persistent connections which enable me to read client's input, respond, and repeat without closing the socket.

Can anyone give me any ideas as to WHY this is the behaviour to be expected in my code? Why is that a output flush causes my input stream to behave unexpectedly? And how do I correctly implement read, write, read with ServerSocktes?

[1424 byte] By [hstang2833a] at [2007-10-3 1:56:17]
# 1

> On line 5 in this code, the read operation is NOT

> blocking and will return -1.

This can only happen if the other end closes the Socket or its output stream or its input stream, or calls Socket.shutdownOutput().

Check your code.

When you get -1, you should close your Socket and stop trying to read - there is no more data.

ejpa at 2007-7-14 18:54:49 > top of Java-index,Archived Forums,Socket Programming...
# 2

I find it odd that adding a socket flush() changes anything (except timings a tiny bit). Here is the implementation java.io.SocketOutputStream's flush():

public void flush() throws IOException {

}

(as inherited from FileOutputStream, which inherits it from OutputStream). Socket.getOutputStream() does a few things too but I don't immediately see how it would cause side effects.

Is that your real code or are you simplifying it for us?

sjasjaa at 2007-7-14 18:54:49 > top of Java-index,Archived Forums,Socket Programming...
# 3

Yes. Socket.getOutputStream().flush() does nothing. If you have a BufferedOutputStream or BufferedWriter or a PrintXXX, flushing that might do something.

But in any case the non-blocking read that returns -1 is simply getting an EOF. Nothing to do with flush(), everything to do with close(). Check your code.

ejpa at 2007-7-14 18:54:49 > top of Java-index,Archived Forums,Socket Programming...