title: Fastest or best way to read from SSLSocket
body: <p>I'm running a multithreaded minimalistic http(s) server (not a web server though) that accepts connections on three server sockets: local, internet and internet-ssl.</p>
  
  <p>Each socket has a so timeout of 1000ms (might be lowered in the future).</p>
  
  <p>The worker threads read requests like this:</p>
  
  <pre><code>byte[] reqBuffer = new byte[512];
  theSocket.getInputStream().read(reqBuffer);
  </code></pre>
  
  <p>The problem now is that with the newly implemented ssl socket the problem with the 1/n-1 record splitting technique arises. Also some clients split in other strange ways when using ssl (4/n-4 etc.) so I thought I might just perform multiple reads like this:</p>
  
  <pre><code>byte[] reqBuffer = new byte[512];
  InputStream is = theSocket.getInputStream();
  int read = is.read(reqBuffer, 0, 128); // inital read - with x/n-x this is very small
  int pos = 0;
  if (read &gt; 0) {
     pos = read;
  }
  int i = 0;
  do {
     read = is.read(reqBuffer, pos, 128);
     if (read &gt; 0) {
        pos += read;
     }
     i++;
  } while(read == 128 &amp;&amp; i &lt; 3); // max. 3 more reads (4 total = 512 bytes) or until less than 128 bytes are read (request should be completely read)
  </code></pre>
  
  <p>Which works with browsers like firefox or chrome and other clients using that technique.</p>
  
  <p>Now my problem is that the new method is much slower. Requests to the local socket are so slow that a script with 2 seconds timeout times out requesting (I have no idea why). Maybe I have some logical problem in my code?</p>
  
  <p>Is there a better way to read from a SSL socket? Because there are up to hundreds or even a thousand requests per second and the new read method slows down even the http requests.</p>
  
  <p>Note: The ssl-socket is not in use at the moment and will not be used until I can fix this problem.</p>
  
  <p>I have also tried reading line for line using a buffered reader since we are talking about http here but the server exploded running out of file descriptors (limit is 20 000). Might have been because of my implementation, though.</p>
  
  <p>I'm thankful for every suggestion regarding this problem. If you need more information about the code just tell me and I will post them asap.</p>
  
  <p><strong>EDIT:</strong>
  I actually put a little bit more thought into what I am trying to do and I realized that it comes down to reading HTTP headers. So the best solution would be to actually read the request line for line (or character for character) and stop reading after x lines or until an empty line (marking the end of the header) is reached.
  My current approach would be to put a BufferedInputStream around the socket's InputStream and read it with an InputStreamReader which is "read" by a BufferedReader (question: does it make sense to use a BufferedInputStream when I'm using a BufferedReader?).
  This BufferedReader reads the request character for character, detects end-of-lines (\r\n) and continues to read until either a line longer than 64 characters is reached, a maximum of 8 lines are read or an empty line is reached (marking the end of the HTTP header). I will test my implementation tomorrow and edit this edit accordingly.</p>
  
  <p><strong>EDIT:</strong>
  I almost forgot to write my results here: It works. On every socket, even faster than the previously working way. Thanks everyone for pointing me in the right direction. I ended up implementing it like this:</p>
  
  <pre><code>List&lt;String&gt; requestLines = new ArrayList&lt;String&gt;(6);
  InputStream is = this.cSocket.getInputStream();
  bis = new BufferedInputStream(is, 1024);
  InputStreamReader isr = new InputStreamReader(bis, Config.REQUEST_ENCODING);
  BufferedReader br = new BufferedReader(isr);
  
  /* read input character for character
  * maximum line size is 768 characters
  * maximum number of lines is 6
  * lines are defined as char sequences ending with \r\n
  * read lines are added to a list
  * reading stops at the first empty line =&gt; HTTP header end
  */
  int readChar; // the last read character
  int characterCount = 0; // the character count in the line that is currently being read
  int lineCount = 0; // the overall line count
  char[] charBuffer = new char[768]; // create a character buffer with space for 768 characters (max line size)
  
  // read as long as the stream is not closed / EOF, the character count in the current line is below 768 and the number of lines read is below 6
  while((readChar = br.read()) != -1 &amp;&amp; characterCount &lt; 768 &amp;&amp; lineCount &lt; 6) {
      charBuffer[characterCount] = (char) readChar; // fill the char buffer with the read character
      if (readChar == '\n' &amp;&amp; characterCount &gt; 0 &amp;&amp; charBuffer[characterCount-1] == '\r') { // if end of line is detected (\r\n)
          if (characterCount == 1) { // if empty line
              break; // stop reading after an empty line (HTTP header ended)
          }
          requestLines.add(new String(charBuffer, 0, characterCount-1)); // add the read line to the readLines list (and leave out the \r)
          // charBuffer = new char[768]; // clear the buffer - not required
          characterCount = 0; // reset character count for next line
          lineCount++; // increase read line count
      } else {
          characterCount++; // if not end of line, increase read character count
      }
  }
  </code></pre>