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!
public class ServerThread
{
public static void 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;
}
}
}