title: Java, server client TCP communication ends with RST
body: <p>I'm trying to figure out if this is normal. Because without errors, a connection should be terminated by:</p>
  
  <pre><code>FIN -&gt;
  &lt;- ACK
  &lt;- FIN
  ACK -&gt;
  </code></pre>
  
  <p>I get this at the end of a TCP connection (over SSL, but i also get it with non-encrypted):</p>
  
  <pre><code>         From     To
  1494    server  client  TCP search-agent &gt; 59185 [PSH, ACK] Seq=25974 Ack=49460 Win=63784 Len=50
  1495    client  server  TCP 59185 &gt; search-agent [ACK] Seq=49460 Ack=26024 Win=63565 Len=0
  1496    client  server  TCP 59185 &gt; search-agent [PSH, ACK] Seq=49460 Ack=26024 Win=63565 Len=23
  1497    client  server  TCP 59185 &gt; search-agent [FIN, ACK] Seq=49483 Ack=26024 Win=63565 Len=0
  1498    server  client  TCP search-agent &gt; 59185 [PSH, ACK] Seq=26024 Ack=49484 Win=63784 Len=23
  1499    client  server  TCP 59185 &gt; search-agent [RST, ACK] Seq=49484 Ack=26047 Win=0 Len=0
  </code></pre>
  
  <p>The client exits normally and reaches <em>socket.close</em>, shouldn't then the connection be shut down normally, without a reset?</p>
  
  <p>I can't find anything about the TCP streams of java on google...  </p>
  
  <p>Here is my code:</p>
  
  <p>Server:</p>
  
  <pre><code>package Security;
  
  import java.io.*;
  import java.net.*;
  
  import javax.net.ServerSocketFactory;
  import javax.net.ssl.*;
  import java.util.*;
  
  public class SSLDemoServer
  {
      private static ServerSocket serverSocket;
      private static final int PORT = 1234;
  
      public static void main(String[] args) throws IOException
      {
          int received = 0;
          String returned; 
          ObjectInputStream input = null;
          PrintWriter output = null;
          Socket client;
  
          System.setProperty("javax.net.ssl.keyStore", "key.keystore");
          System.setProperty("javax.net.ssl.keyStorePassword", "vwpolo");
          System.setProperty("javax.net.ssl.trustStore", "key.keystore");
          System.setProperty("javax.net.ssl.trustStorePassword", "vwpolo");
  
          try
          {
              System.out.println("Trying to set up server ...");
              ServerSocketFactory factory = SSLServerSocketFactory.getDefault();
              serverSocket = factory.createServerSocket(PORT);
  
              System.out.println("Server started!\n");
          }
          catch (IOException ioEx)
          {
              System.out.println("Unable to set up port!");
              ioEx.printStackTrace();
              System.exit(1);
          }
  
          while(true)
          {
              client = serverSocket.accept();
              System.out.println("Client trying to connect...");
  
              try
              {
                  System.out.println("Trying to create inputstream...");
                  input = new ObjectInputStream(client.getInputStream());
                  System.out.println("Trying to create outputstream...");
                  output = new PrintWriter(client.getOutputStream(), true);
                  System.out.println("Client successfully connected!");
  
                  while( true )
                  {
                      received = input.readInt();
                      returned = Integer.toHexString(received);
                      System.out.print(" " + received);
                      output.println(returned.toUpperCase());
                  }
              }
              catch(SSLException sslEx)
              {
                  System.out.println("Connection failed! (non-SSL connection?)\n");
                  client.close();
                  continue;
              }
              catch(EOFException eofEx)
              {
                  System.out.println("\nEnd of client data.\n");
              }
              catch(IOException ioEx)
              {
                  System.out.println("I/O problem! (correct inputstream?)");
              }
  
              try {
                  input.close();
                  output.close();
              }
              catch (Exception e) {
              }
              client.close();
              System.out.println("Client closed.\n");
          }
      }
  }
  </code></pre>
  
  <p>Client:</p>
  
  <pre><code>package Security;
  
  import java.io.*;
  import java.net.*;
  import javax.net.ssl.*;
  
  import java.util.*;
  
  public class SSLDemoClient
  {
      private static InetAddress host;
      private static final int PORT = 1234;
  
      public static void main(String[] args)
      {
          System.setProperty("javax.net.ssl.keyStore", "key.keystore");
          System.setProperty("javax.net.ssl.keyStorePassword", "vwpolo");
          System.setProperty("javax.net.ssl.trustStore", "key.keystore");
          System.setProperty("javax.net.ssl.trustStorePassword", "vwpolo");
  
          System.out.println("\nCreating SSL socket ...");
          SSLSocket socket = null;
          try
          {
              host = InetAddress.getByName("192.168.56.101");
              SSLSocketFactory factory = (SSLSocketFactory)
              SSLSocketFactory.getDefault();
              socket = (SSLSocket) factory.createSocket(host, PORT);
              socket.startHandshake();
          }
          catch(UnknownHostException uhEx)
          {
              System.out.println("\nHost ID not found!\n");
              System.exit(1);
          }
          catch(SSLException sslEx)
          {
              System.out.println("\nHandshaking unsuccessful ...");
              System.exit(1);
          } 
          catch (IOException e) {
              e.printStackTrace();
          }
          System.out.println("\nHandshaking succeeded ...\n");
  
          SSLClientThread client = new SSLClientThread(socket);
          SSLReceiverThread receiver = new SSLReceiverThread(socket);
  
          client.start();
          receiver.start();
  
          try
          {
              client.join();
              receiver.join();
              System.out.println("Trying to close...");
              socket.close();
          }
          catch(InterruptedException iEx)
          {
              iEx.printStackTrace();
          } 
          catch(IOException ioEx)
          {
              ioEx.printStackTrace();
          }
  
          System.out.println("\nClient finished.");
      }
  }
  
  
  class SSLClientThread extends Thread
  {
      private SSLSocket socket;
  
      public SSLClientThread(SSLSocket s)
      {
          socket = s;
      }
  
      public void run() 
      {
          try
          {
              ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
  
              for( int i = 1; i &lt; 1025; i++)
              {
                  output.writeInt(i);
                  sleep(10);
                  output.flush();
              } 
  
              output.flush();
              sleep(1000);
              output.close();
          }
          catch(IOException ioEx)
          {
              System.out.println("Socket closed or unable to open socket.");
          }
          catch(InterruptedException iEx)
          {
              iEx.printStackTrace();
          }
      }
  }
  
  
  class SSLReceiverThread extends Thread
  {
      private SSLSocket socket;
  
      public SSLReceiverThread(SSLSocket s)
      {
          socket = s;
      }
  
      public void run()
      {
          String response = null;
          BufferedReader input = null;
  
          try
          {
              input = new BufferedReader(
                      new InputStreamReader(socket.getInputStream()));
  
              try
              {
                  response = input.readLine();
                  while(!response.equals(null)) 
                  {
                      System.out.print(response + " ");
                      response = input.readLine();
                  } 
              }
              catch(Exception e)
              {
                  System.out.println("\nEnd of server data.\n");
              }    
  
              input.close();
  
          }
          catch(IOException ioEx)
          {
              ioEx.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <hr>
  
  <p>Thanks a lot, on a non-SSL connection, I now get a nice orderly connection shutdown without a reset.</p>
  
  <p>BUT apparently this method is not supported by <code>SSLSocket</code>? When I try it in my SSL client, I get the following exception:</p>
  
  <pre><code>Exception in thread "Thread-0" java.lang.UnsupportedOperationException: The method shutdownOutput() is not supported in SSLSocket
      at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.shutdownOutput(Unknown Source)
      at Security.SSLClientThread.run(SSLDemoClient.java:99)
  </code></pre>
  
  <p>My new code looks like this:</p>
  
  <pre><code>package Security;
  
  import java.io.*;
  import java.net.*;
  
  import javax.net.SocketFactory;
  import javax.net.ssl.*;
  
  public class SSLDemoClient
  {
      private static InetAddress host;
      private static Socket socket;
      private static final int PORT = 1234;
  
      public static void main(String[] args)
      {
          System.setProperty("javax.net.ssl.keyStore", "key.keystore");
          System.setProperty("javax.net.ssl.keyStorePassword", "vwpolo");
          System.setProperty("javax.net.ssl.trustStore", "key.keystore");
          System.setProperty("javax.net.ssl.trustStorePassword", "vwpolo");
  
          System.out.println("\nCreating SSL socket ...");
  
          try
          {
              host = InetAddress.getByName("192.168.56.101");
              SocketFactory socketFactory = SSLSocketFactory.getDefault();
              socket = socketFactory.createSocket(host, PORT);
          }
          catch(UnknownHostException uhEx)
          {
              System.out.println("\nHost ID not found!\n");
              System.exit(1);
          }
          catch(SSLException sslEx)
          {
              System.out.println("\nHandshaking unsuccessful ...");
              System.exit(1);
          } 
          catch (IOException e) {
              e.printStackTrace();
          }
          System.out.println("\nHandshaking succeeded ...\n");
  
          SSLClientThread client = new SSLClientThread(socket);
          SSLReceiverThread receiver = new SSLReceiverThread(socket);
  
          client.start();
          receiver.start();
  
          try
          {
              client.join();
              receiver.join();
              System.out.println("Trying to close...");
  
              socket.close();
          }
          catch(InterruptedException iEx)
          {
              iEx.printStackTrace();
          } 
          catch(IOException ioEx)
          {
              ioEx.printStackTrace();
          }
  
          System.out.println("\nClient finished.");
      }
  }
  
  
  class SSLClientThread extends Thread
  {
      private Socket socket;
  
      public SSLClientThread(Socket s)
      {
          socket = s;
      }
  
      public void run() 
      {
          try
          {
              ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
  
              for( int i = 1; i &lt; 1025; i++)
              {
                  output.writeInt(i);
                  sleep(10);
                  output.flush();
              } 
  
              output.flush();
              sleep(1000);
              socket.shutdownOutput();
          }
          catch(IOException ioEx)
          {
              System.out.println("Socket closed or unable to open socket.");
          }
          catch(InterruptedException iEx)
          {
              iEx.printStackTrace();
          }
      }
  }
  
  
  class SSLReceiverThread extends Thread
  {
      private Socket socket;
  
      public SSLReceiverThread(Socket s)
      {
          socket = s;
      }
  
      public void run()
      {
          String response = null;
          BufferedReader input = null;
  
          try
          {
              input = new BufferedReader(
                      new InputStreamReader(socket.getInputStream()));
  
              try
              {
                  response = input.readLine();
                  while(!response.equals(null)) 
                  {
                      System.out.print(response + " ");
                      response = input.readLine();
                  } 
              }
              catch(Exception e)
              {
                  System.out.println("\nEnd of server data.\n");
              }    
  
              socket.shutdownInput();
  
          }
          catch(IOException ioEx)
          {
              ioEx.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>Am I not using it correcty? Or is my SSLSocket not correct? Because with a non-SSL connection there is no problem.</p>