title: Java socket programming: Connection reset despite closing socket?
body: <p>I am currently coding a simple TCP chat client-server application which works with sockets. A client connects to the server and as soon as it gets accepted, a new worker thread is created to listen for client input. Connecting to the sever (localhost at port 8818) works fine, but as soon as the worker thread starts listening for more client input after the login <code>a java.net.SocketException: Connection reset</code> is thrown (see stack trace below). I am aware that one possible source of this exception can be a socket that hasn't been closed properly or forcefully by either the server or the client. Therefore, my assumption is that I am not handling the closing of my client socket properly which causes the connection to reset.<br/><br/>
  What I would like to achieve: 
  The worker listens for client input, as long as this is not null, requests (e.g. a simple login) are processed, otherwise, the socket is closed (see code excerpts below). My client receives a 'Login Successful' message from the server indicating that my <code>handleLogin()</code> function works, but instead of closing the socket after receiving no more input from the client, the server seems to just reset, even though <code>clientSocket.close()</code> is issued after the while loop.</p>
  
  <p><strong>Server.java</strong></p>
  
  <pre><code>@Override
      public void run() {
  
          try {
  
              ServerSocket serverSocket = new ServerSocket(serverPort);
  
              while (true) {
  
                  // Accept connection(s) from new chat client(s)
                  System.out.println("SERVER: WAITING TO ACCEPT CLIENT CONNECTIONS ...");
                  Socket clientSocket = serverSocket.accept();
                  System.out.println("SERVER: CONNECTION ACCEPTED FROM: " + clientSocket);
                  // Process client request in separate Thread
                  WorkerThread worker = new WorkerThread(this, clientSocket);
                  workerList.add(worker);
                  worker.start();
              }
  
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  </code></pre>
  
  <p><strong>WorkerThread.java</strong></p>
  
  <pre><code> @Override
      public void run() {
  
          try {
              handleClientSocket();
          } catch (IOException e) {
              e.printStackTrace();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
  
      }
  
  
      private void handleLogin(OutputStream outputStream, String[] tokens) throws IOException {
  
          if (tokens.length != 3) {
              outputStream.write("LOGIN FAILED!\n".getBytes());
                  return;
          }
  
          // Extract username and password from user input
          String username = tokens[1];
          String password = tokens[2];
  
          if (username.equals("anna") &amp;&amp; password.equals("anna")) {
  
              outputStream.write("Login successful!\n".getBytes());
  
          } else {
              outputStream.write("Error logging in!\n".getBytes());
          }
  
      }
  
      private void handleClientSocket() throws IOException, InterruptedException {
  
          InputStream inputStream = clientSocket.getInputStream();
          this.outputStream = clientSocket.getOutputStream();
  
          BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
          String line;
  
          // THIS IS WHERE THE EXCEPTION OCCURS AFTER CLIENT HAS LOGGED IN SUCCESSFULLY
          while ((line = bufferedReader.readLine()) != null) {
  
              String[] tokens = StringUtils.split(line);
  
              if (tokens.length &gt; 0 &amp;&amp; tokens != null) {
  
                  String command = tokens[0];
  
                  // Evaluate the entered command and handle the request accordingly
  
                  if ("login".equalsIgnoreCase(command)) {
                      handleLogin(outputStream, tokens);
                  } 
  
                  // process other commands ...  
  
              }
          }
  
          clientSocket.close();   // POSSIBLY WORNG WAY OF CLOSING THE CLIENT SOCKET?
      }
  </code></pre>
  
  <p><strong>Client.java</strong></p>
  
  <pre><code>import java.io.*;
  import java.net.Socket;
  
  public class Client {
  
      private final String serverName;
      private final int serverPort;
      private Socket mySocket;
      private OutputStream serverOut;
      private InputStream serverIn;
  
      public Client(String serverName, int serverPort) {
          this.serverName = serverName;
          this.serverPort = serverPort;
      }
  
      private boolean connect() {
  
          try {
              mySocket = new Socket(serverName, serverPort);
              serverOut = mySocket.getOutputStream();
              serverIn = mySocket.getInputStream();
              return true;
          } catch (IOException e) {
              e.printStackTrace();
          }
          return false;
      }
  
      private void login(String username, String password) throws IOException {
          String command = "login " + username + " " + password + "\n";
          serverOut.write(command.getBytes());
      }
  
      public static void main(String[] args) throws IOException {
  
          Client client = new Client("localhost", 8818);
  
          if (client.connect()) {                             
              System.out.println("Connection successful!");   
              client.login("anna", "anna");                   
  
          } else {
              System.err.println("Connection failed ...");
          }
  
      }
  
  }
  </code></pre>
  
  <p><strong>Stack Trace</strong></p>
  
  <pre><code>java.net.SocketException: Connection reset
      at java.net.SocketInputStream.read(SocketInputStream.java:189)
      at java.net.SocketInputStream.read(SocketInputStream.java:121)
      at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
      at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
      at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
      at java.io.InputStreamReader.read(InputStreamReader.java:184)
      at java.io.BufferedReader.fill(BufferedReader.java:161)
      at java.io.BufferedReader.readLine(BufferedReader.java:324)
      at java.io.BufferedReader.readLine(BufferedReader.java:389)
      at WorkerThread.handleClientSocket(WorkerThread.java:70)
      at WorkerThread.run(WorkerThread.java:45)
  </code></pre>
  
  <p>When I test my server with PUTTY (i.e. by connecting to localhost and then issuing commands in PUTTY's terminal), everything works just fine.<br/><br>
  I am still fairly new to socket programming, so I also might have a  logic flaw here. Any help will be much appreciated as I really would like to continue this project. 
  Thanks in advance!  </p>