title: Socket connection reset still not understood
body: <p>What is the problem:</p>
  
  <p>It appears that spuriously a Java Socket based server program resets it's connection to a Java socket based client in the midst of an established connection, despite SO_TIMEOUT settings for data transfer being set to "infinite"</p>
  
  <p>I tested the server on:</p>
  
  <p>Linux Ubuntu 14.04 LTS Kernel 3.13.0-29-generic Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
  and on
  Windows 8.1 Version 6.3.9600 Java(TM) SE Runtime Environment (build 1.7.0_51-b13)</p>
  
  <p>And there is a difference. On Windows the server doesn't accept connections when all threads are busy and the backlog is used and so it should be. On Linux connections are accepted, data can be written and flushed (in addition with TCP_NODELAY) but at a subsequent read by the client its receives "Connection Reset" every now and then. I get no exceptions at the server side.
  There is no change in behaviour if the client is ran under Windows or Linux, nor is there any difference running the server on a loopback address, a local network address or and external network address.</p>
  
  <p>Any help or contributions would be very welcome. I'm here to learn too, so if I made coding errors just tell me.</p>
  
  <p>In earlier posts there was no source added rather than a link to a JAR and source images on my website. I agree this is no common practice here, so I made a condensed version which also reveals the problem. Note that all settings are deliberately chosen to bring the server in an overloaded state and timeouts for connections and reads are set to "infinite". I do realize that these are not the ones one would choose in "real life", but merely to generate the "Connection Reset".</p>
  
  <p>This is the code for the client:</p>
  
  <pre><code>package resetconntest;
  
  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.io.PrintWriter;
  import java.net.InetSocketAddress;
  import java.net.Socket;
  import java.util.concurrent.Semaphore;
  
  class MiniClient {
  
    static boolean SHOW_EXC_ONLY = true;   // show exceptions only
    static int     THREADS       = 64;     // number of "simultaneous connections"
    static int     LOOPS         = 256;    // total number of connections
    static String  HOST          = "192.168.0.10"; // server hostname 
    static int     PORT          = 7272;           // server port
    static int     CONN_TIMEOUT  = 0;      // keep infinite connect time for test
    static int     SO_TIMEOUT    = 0;      // keep infinite read    time for test
    static int     SO_LINGER     = -1;     // no linger
    static boolean REUSE_ADDRESS = false;  // chosen for test
    static boolean TCP_NODELAY   = true;   // small blocks, so no Nagle 
    static boolean KEEP_ALIVE    = false;  // chosen for test
    static int     TRAFFIC_CLASS = 0;      // if used, use mask as for ToS
  
    public static void main ( String[] args ) {
      new MiniClient().runTest ();
      System.exit ( 0 );
    }
  
    MiniClient () {}
  
    void runTest () {
      Object syncer = new Object();
      System.out.println ( "--&gt; start MiniClient" );
      try {
        Semaphore semaphore = new Semaphore ( THREADS );
        for ( int x = 0 ; x &lt; LOOPS ; x++ ) {
          semaphore.acquireUninterruptibly ();
          new Requester ( syncer ,x + 1 ,semaphore ).start(); 
        }
        while ( semaphore.availablePermits() &lt; THREADS ) {
          Thread.sleep ( 100 );
        }
      } catch ( Throwable anyThrown ) {
        synchronized ( syncer ) {
          System.out.println ( "--&gt; throwable in main" );
          anyThrown.printStackTrace ( System.out );
          System.out.println ( "&lt;-- throwable in main" );
        }
      }
      System.out.println ( "&lt;-- end MiniClient" );
    }
  
    class Requester extends Thread {
      Object    syncer;
      String    index;
      Semaphore semaphore;
  
      Requester ( Object syncer ,int index ,Semaphore semaphore ) {
        this.syncer    = syncer;
        this.index     = Integer.toString ( index );
        this.semaphore = semaphore;
      }
  
      public void run () {
        try {
          Socket socket = new Socket ();
          socket.connect         ( new InetSocketAddress ( HOST ,PORT ) ,CONN_TIMEOUT );
          socket.setSoTimeout    ( SO_TIMEOUT );
          socket.setSoLinger     ( (SO_LINGER &gt;= 0) ,SO_LINGER );
          socket.setReuseAddress ( REUSE_ADDRESS );
          socket.setTcpNoDelay   ( TCP_NODELAY );
          socket.setKeepAlive    ( KEEP_ALIVE );
          if ( TRAFFIC_CLASS != 0 ) socket.setTrafficClass ( TRAFFIC_CLASS );
          PrintWriter    out = new PrintWriter    ( new OutputStreamWriter ( socket.getOutputStream() ) );
          BufferedReader in  = new BufferedReader ( new InputStreamReader  ( socket.getInputStream()  ) );
  
          if ( dialog ( "aaaaa" ,out ,in ) )
          if ( dialog ( "bbbbb" ,out ,in ) )
               dialog ( "close" ,out ,in );
  
          socket.shutdownInput();
          socket.shutdownOutput();
          in.close();
          out.close();
          socket.close ();
        } catch ( Throwable anyThrown ) {
          synchronized ( syncer ) {
            System.out.println ( "--&gt; throwable in client thread:" + index );
            anyThrown.printStackTrace ( System.out );
            System.out.println ( "&lt;-- throwable in client thread:" + index );
          }
        }
        semaphore.release ();
      }
  
      boolean dialog ( String         text
                      ,PrintWriter    out 
                      ,BufferedReader in ) throws Throwable {
        String msg = index + ':' + text;
        try {
          if ( SHOW_EXC_ONLY == false ) synchronized ( syncer ) { System.out.println ( "--&gt; send: " + msg ); }
          out.println ( msg );
          out.flush();
          String resp = in.readLine();
          if ( resp == null ) {
            synchronized ( syncer ) { System.out.println ( "&lt;-- got EOF after: " + msg ); }
            return false;
          }
          if ( SHOW_EXC_ONLY == false ) synchronized ( syncer ) { System.out.println ( "&lt;-- received: " + resp ); }
        } catch ( Throwable anyThrown ) {
          synchronized ( syncer ) {
            System.out.println ( "--&gt; throwable in client thread:" + index );
            System.out.println ( "--&gt; at processing message: " + msg );
            anyThrown.printStackTrace ( System.out );
            System.out.println ( "&lt;-- at processing message: " + msg );
            System.out.println ( "&lt;-- throwable in client thread:" + index );
          }
          return false;
        }
        return true;
      }
    } // end of inner class
  
  } // end of code
  </code></pre>
  
  <p>And this is the code for the server:</p>
  
  <pre><code>package resetconntest;
  
  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.io.PrintWriter;
  import java.net.InetAddress;
  import java.net.InetSocketAddress;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.util.concurrent.Semaphore;
  
  class MiniServer {
  
    static boolean SHOW_EXC_ONLY        = false;  // show messages and exceptions
    static String  HOST                 = "192.168.0.10";  // host name   binded to
    static int     PORT                 = 7272;            // port number binded to 
    static int     ACC_TIMEOUT          = 0;      // keep timeout for accept infinite for test
    static boolean REUSE_SERVER_ADDRESS = false;  // chosen for test
    static int     BACKLOG              = 2;      // keep low for test
    static int     THREADS              = 8;      // keep low for test
    static int     SO_TIMEOUT           = 0;      // keep infinite read timeout for test
    static int     SO_LINGER            = -1;     // no lingering
    static boolean REUSE_ACC_ADDRESS    = false;  // chosen for test
    static boolean TCP_NODELAY          = true;   // small blocks, so no Nagle
    static boolean KEEP_ALIVE           = false;  // chosen for test
    static int     TRAFFIC_CLASS        = 0;      // if used, use mask as for ToS
    static int     PROCESS_DELAY        = 500;    // simulate long message processing 0.5 sec
  
    public static void main ( String[] args ) {
      new MiniServer().runTest ();
      System.exit ( 0 );
    }
  
    MiniServer () {}
  
    public void runTest () {
      Object syncer = new Object();
      System.out.println ( "--&gt; start MiniServer" );
      try {
        InetSocketAddress socketAddress = new InetSocketAddress ( InetAddress.getByName ( HOST ), PORT );
        ServerSocket      serverSocket  = new ServerSocket ();
        serverSocket.bind            ( socketAddress ,BACKLOG );
        serverSocket.setReuseAddress ( REUSE_SERVER_ADDRESS );
        serverSocket.setSoTimeout    ( ACC_TIMEOUT );
        Semaphore semaphore = new Semaphore ( THREADS );
        Socket    accepted;
        while ( true ) {
          semaphore.acquireUninterruptibly();
          accepted = serverSocket.accept();
          new Servicer ( syncer ,accepted ,semaphore ).start(); 
        }
        // never reached, gives the warning at server construction.
        // to end the server, just use the old fashioned blunt CTRL-C
        // while ( semaphore.availablePermits() &lt; THREADS ) {
        //   Thread.sleep ( 100 );
        // }
        // serverSocket.close ();
      } catch ( Throwable anyThrown ) {
        synchronized ( syncer ) {
          System.out.println ( "--&gt; throwable in main" );
          anyThrown.printStackTrace ( System.out );
          System.out.println ( "&lt;-- throwable in main" );
        }
      }
      System.out.println ( "&lt;-- end MiniServer" );
    }
  
    class Servicer extends Thread {
      Object    syncer;
      Socket    socket;
      Semaphore semaphore;
  
      Servicer ( Object    syncer
                ,Socket    socket
                ,Semaphore semaphore ) { 
        this.syncer    = syncer;
        this.socket    = socket;
        this.semaphore = semaphore;
      }
  
      public void run () {
        try {
          socket.setSoTimeout    ( SO_TIMEOUT );
          socket.setSoLinger     ( (SO_LINGER &gt;= 0) ,SO_LINGER );
          socket.setReuseAddress ( REUSE_ACC_ADDRESS );
          socket.setTcpNoDelay   ( TCP_NODELAY );
          socket.setKeepAlive    ( KEEP_ALIVE );
          if ( TRAFFIC_CLASS != 0 ) socket.setTrafficClass ( TRAFFIC_CLASS );
          BufferedReader in =  new BufferedReader( new InputStreamReader  ( socket.getInputStream()  ) );
          PrintWriter    out = new PrintWriter   ( new OutputStreamWriter ( socket.getOutputStream() ) );
          String         clientMessage;
          while ( true ) {
            clientMessage = in.readLine ();
            if ( clientMessage == null ) {
              synchronized ( syncer) { System.out.println ( "&lt;-&gt; received end of file from accepted socket" ); }
              break;
            }
            if ( SHOW_EXC_ONLY == false ) synchronized ( syncer ) { System.out.println ( "client said: " + clientMessage ); }
            if ( PROCESS_DELAY &gt; 0 ) Thread.sleep ( PROCESS_DELAY );
            out.println ( "echo: " + clientMessage );
            out.flush();
            if ( clientMessage.indexOf ( "close" ) &gt;= 0 ) break;
          }
          socket.shutdownInput();
          socket.shutdownOutput();
          in.close();
          out.close();
          socket.close();
        } catch ( Throwable anyThrown ) {
          synchronized ( syncer ) {
            System.out.println ( "--&gt; throwable in server thread" );
            anyThrown.printStackTrace ( System.out );
            System.out.println ( "&lt;-- throwable in server thread" );
          }
        }
        semaphore.release();
      }
  
    } // end of inner class
  
  } // end of code
  </code></pre>