ServerSocket connection reset under weird circumstances

Hi all,

I'm trying to write a very simple TCP/IP server, to provide XML data to a web browser. This should be dead easy, but I'm encountering something weird. I hope you can help me.

I can successfully create a ServerSocket on a given port, and accept connections. The problem arises when I try to send data to the client. I obtain the OutputStream from the Socket, write some bytes to it, flush, and close.

Oddly enough, my web browser usually (but not always) tells me that the server reset the connection while the page was loading. I played around with the code, and discovered that if I make the thread sleep before closing the output stream, everything works fine. It's almost as though the data is being put on the stream, and I'm closing the stream in the middle of the transfer. Weirder still, if I send a really large string to the client, the problem disappears.

Has anyone else encountered this problem? How did you resolve it? Is there any way of monitoring the transfer, so that the connection is closed only when it has finished?

Below is some code that demonstrates the problem. If you leave the string length as small, and leave the thread sleep code commented out, the problem should appear. If you reinstate the sleep code, or increase the string length to 10000 or more, the problem should disappear.

The client web browser connects at: http://127.0.0.1:5555

Thank you very much, in advance!

publicclass ServerThread

{

publicstaticvoid main( String[] aArgs )

{

//

// Build a string of variable length.

// NOTE: If the string length is small, the problem appears

//and must be addressed by sleeping the thread.

//If the string length is large (>10000), no sleeping

//is necessary.

//

// The string length

int lStringLength = 10;

// Build a long nonsense XML string

StringBuilder lBuilder =new StringBuilder();

lBuilder.append("<data>\n" );

for (int i = 0; i < lStringLength; i++ ){

lBuilder.append("<data_point>Testing" )

.append( i )

.append("</data_point>\n" );

}

lBuilder.append("</data>" );

//

// The server.

//

try{

// Initialize a server socket

ServerSocket lServerSocket =new ServerSocket( 5555 );

// Iterate indefinitely

while (true ){

// Listen for a connection to this socket, and accept

Socket lSocket = lServerSocket.accept();

// Get the socket output stream

OutputStream lOutputStream = lSocket.getOutputStream();

// Write the data to the output stream

lOutputStream.write( lBuilder.toString().getBytes() );

// Flush the output stream

lOutputStream.flush();

/*

// Sleep for awhile

// NOTE: If the thread closes the output stream immediately,

//the client doesn't receive the data!!

try {

Thread.sleep( 1000 );

} catch (InterruptedException ex) {

ex.printStackTrace();

return;

}

*/

// Close the output stream and socket

lOutputStream.close();

lSocket.close();

}

}catch (IOException e){

e.printStackTrace();

return;

}

}

}

[4826 byte] By [cjba] at [2007-11-27 10:18:54]
# 1

The sleep is obviously redundant. The browser is still trying to send the request to the server. The server hasn't read the request, and has closed the socket, hence the browser gets a reset while sending. Have the server read the socket. Also remove the second close (the socket), it is redundant. Closing the output stream is sufficient.

ejpa at 2007-7-28 16:54:24 > top of Java-index,Core,Core APIs...
# 2

Interesting...that makes sense. Do you know of an easy way to tell when the request has been entirely received, other than to read from the input stream in a loop? Is there a better way than this, for example:

InputStream lInputStream = lSocket.getInputStream();

BufferedReader lReader = new BufferedReader( new InputStreamReader( lInputStream ) );

String lStr;

while ( ( lStr = lReader.readLine() ) != null && ( lStr.trim().length() > 0 ) )

;

cjba at 2007-7-28 16:54:24 > top of Java-index,Core,Core APIs...
# 3

That's perfect for HTTP.

ejpa at 2007-7-28 16:54:24 > top of Java-index,Core,Core APIs...
# 4

Thank you very much, ejp...you've saved me some headaches!

cjba at 2007-7-28 16:54:24 > top of Java-index,Core,Core APIs...