Name: bsC130419 Date: 06/12/2001
java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)
NOTE: This problem can be reproduced on any Windows system having Winsock 2.
Also, I tested jdk1.3, jdk1.3.0_01, jdk1.3.0_02, jdk1.3.1, and jdk1.4. They all
seem to use the same native code. (socket_md.c)
Compile 'Server.java' and run it.
Compile 'Client.java' and run it. (it takes the hostname as an argument; the
port is hardcoded)
-------------------------------------------------------------------------------
import java.net.*;
import java.io.*;
public class Server {
public Server( int port ) {
try {
ServerSocket sSocket = new ServerSocket( port );
System.out.println( "Listening..." );
Socket s = sSocket.accept();
System.out.println( "Got connection from: " +
s.getInetAddress().getHostAddress() + ":" + s.getPort() );
PrintWriter writer =
new PrintWriter( new OutputStreamWriter(s.getOutputStream())
);
new Reader( s.getInputStream() ).start();
sSocket.close();
}
catch( IOException ex ) {
ex.printStackTrace();
}
}
public static void main( String args[] ) {
new Server( 8777 );
}
class Reader extends Thread {
InputStream is;
Reader( InputStream is ) {
this.is = is;
}
public void run() {
int c;
try {
while( (c = is.read()) != -1 ) {
System.out.print( (char)c );
}
}
catch( IOException ex ) {
ex.printStackTrace();
}
}
}
}
-------------------------------------------------------------------------------
import java.net.*;
import java.io.*;
public class Client {
public Client( String host, int port ) {
Socket s = null;
try {
s = new Socket( host, port );
s.setSoLinger( true, 0 );
System.out.println( "SO_LINGER: " + s.getSoLinger() );
PrintWriter writer = new PrintWriter( new OutputStreamWriter(
s.getOutputStream()) );
writer.println( "Client says hello..." );
writer.println( "Client says goodbye..." );
writer.flush();
//close the socket
//this should send 'RST' (it doesn't)
s.close();
}
catch( IOException ex ) {
ex.printStackTrace();
}
}
public static void main( String args[] ) {
if( args.length != 1 ) {
System.err.println( "Usage: java Client hostname" );
System.exit( -1 );
}
new Client( args[0], 8777 );
}
}
-------------------------------------------------------------------------------
Run the Client from Windows. Then, run it from Unix and notice the difference.
Under Unix, the Client will abort thereby sending 'RST' and the Server will
receive the exception. (i.e. Connection Reset) On Windows with Winsock 2, the
Server will receive 'EOF' as opposed to being aborted. (i.e. graceful close)
If you are still not convinced, run 'tcpdump'
It's critical that this bug be fixed because no support for SO_LINGER, and more
importantly 'abortive close' is very limiting in itself. For example, it makes
it impossible for one to write a browser like Netscape in Java without using
Winsock native API effectively reinventing the wheel.
(Review ID: 126237)
======================================================================