title: How do I handle ServerSocketChannel.accept() IOException: too many open files in NIO?
body: <p>I'm having a problem with one of my servers, on Friday morning I got the following IOException:</p>
  <pre><code>11/Sep/2015 01:51:39,524 [ERROR] [Thread-1] - ServerRunnable: IOException: 
  java.io.IOException: Too many open files
      at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) ~[?:1.7.0_75]
      at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:241) ~[?:1.7.0_75]
      at com.watersprint.deviceapi.server.ServerRunnable.acceptConnection(ServerRunnable.java:162) [rsrc:./:?]
      at com.watersprint.deviceapi.server.ServerRunnable.run(ServerRunnable.java:121) [rsrc:./:?]
      at java.lang.Thread.run(Thread.java:745) [?:1.7.0_75]
  </code></pre>
  <p>Row 162 of the ServerRunnable class is in the method below, it's the <code>ssc.accept()</code> call.</p>
  <pre><code>private void acceptConnection(Selector selector, SelectionKey key) {
  
      try {
          ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
          SocketChannel sc = ssc.accept();
          socketConnectionCount++;
  
          /*
           * Test to force device error, for debugging purposes
           */
          if (brokenSocket
                  &amp;&amp; (socketConnectionCount % brokenSocketNumber == 0)) {
  
              sc.close();
  
          } else {
  
              sc.configureBlocking(false);
              log.debug(&quot;*************************************************&quot;);
              log.debug(&quot;Selector Thread: Client accepted from &quot;
                      + sc.getRemoteAddress());
  
              SelectionKey newKey = sc.register(selector,
                      SelectionKey.OP_READ);
              ClientStateMachine clientState = new ClientStateMachine();
              clientState.setIpAddress(sc.getRemoteAddress().toString());
              clientState.attachSelector(selector);
              clientState.attachSocketChannel(sc);
              newKey.attach(clientState);
  
          }
  
      } catch (ClosedChannelException e) {
  
          log.error(&quot;ClosedChannelException: &quot;, e);
          ClientStateMachine clientState = (ClientStateMachine)key.attachment();
          database.insertFailedCommunication(clientState.getDeviceId(),
                  clientState.getIpAddress(),
                  clientState.getReceivedString(), e.toString());
          key.cancel();
  
      } catch (IOException e) {
          log.error(&quot;IOException: &quot;, e);
          
      }
  
  }
  </code></pre>
  <p>How should I handle this? reading up on the error it appears to be a setting in the Linux OS that limits the number of open files a process can have.
  Judging from that, and <a href="https://stackoverflow.com/questions/4289447/java-too-many-open-files">this question here</a>, it appears that I am not closing sockets correctly (The server is currently serving around 50 clients). Is this a situation where I need a timer to monitor open sockets and time them out after an extended period?</p>
  <p>I have some cases where a client can connect and then not send any data once the connection is established. I thought I had handled those cases properly.</p>
  <p>It's my understanding that a non-blocking NIO server has very long timeouts, is it possible that if I've missed cases like this they might accumulate and result in this error?</p>
  <p>This server has been running for three months without any issues.
  After I go through my code and check for badly handled / missing cases, what's the best way to handle this particular error? Are there other things I should consider that might contribute to this?</p>
  <p>Also, (Maybe this should be another question) I have log4j2 configured to send emails for log levels of error and higher, yet I didn't get an email for this error. Are there any reasons why that might be? It usually works, the error was logged to the log file as expected, but I never got an email about it. I should have gotten plenty as the error occurred every time a connection was established.</p>