src/main/java/pityoulish/sockets/server/SimplisticSocketHandler.java
public ByteBuffer readRequest(Socket sock)
    throws Exception
  {
    // to avoid permanent blocking by misbehaving clients:
    // - set a timeout on the socket
    // - track how long it takes to receive the request, cancel if necessary
    //   The client could send byte by byte to avoid timeouts.

    sock.setSoTimeout(RCV_SO_TIMEOUT);
    final long started = System.currentTimeMillis();
    final long deadline = started + RCV_DEADLINE;

    byte[] data = new byte[MAX_REQUEST_SIZE];

    InputStream is = sock.getInputStream();

    //@@@ This logic is specific to TLVs; also needed by clients... refactor!
    //@@@ Send error response to bogus request, or just drop the connection?

    // Read the first 4 bytes of data, expected in first block of data.
    // Clients that try to send data byte for byte will be kicked out.
    int pos = is.read(data, 0, 4);
    if (pos < 4)
     {
       throw cancelRequest
         (Catalog.RECEIVE_INITIAL_BLOCK_TOO_SMALL_0.format(), null, sock);
     }

    // Requests are in TLV format, see ASN.1 BER
    // byte 1: type of the request
    // byte 2: length of length, value 0x82 indicating 2 bytes for the length
    // byte 3: upper byte of length
    // byte 4: lower byte of length

    if ((data[0] & 0xe0) != 0xe0) // expect bits: 111xxxx
     {
       throw cancelRequest(Catalog.RECEIVE_BAD_TYPE_1
                           .format("0x"+Integer.toHexString(data[0] & 0xff)),
                           null, sock);
     }

    if (data[1] != MsgBoardTLV.LENGTH_OF_LENGTH_2)
     {
       throw cancelRequest(Catalog.RECEIVE_BAD_LEN_OF_LEN_1
                           .format("0x"+Integer.toHexString(data[1] & 0xff)),
                           null, sock);
     }

    int length = ((data[2] & 0xff)<<8) + (data[3] & 0xff);
    int size = length+4;
    if (size > MAX_REQUEST_SIZE)
     {
       throw cancelRequest(Catalog.RECEIVE_TOO_LONG_2
                           .format(length, MAX_REQUEST_SIZE), null, sock);
     }

    while (pos < size)
     {
       if (System.currentTimeMillis() > deadline)
        {
          throw cancelRequest
            (Catalog.RECEIVE_DEADLINE_EXPIRED_0.format(), null, sock);
        }

       int count = is.read(data, pos, data.length-pos);
       if (count < 0)
        {
          throw cancelRequest
            (Catalog.RECEIVE_INCOMPLETE_0.format(), null, sock);
        }
       pos += count;
     }

    final long ended = System.currentTimeMillis();
    //System.out.println("received request of "+(length+4)+
    //                    " bytes in "+(ended-started)+" ms");

    ByteBuffer request = ByteBuffer.wrap(data, 0, size);
    return request;

  }
/**
   * Reads a request from a socket and returns it.
   *
   * @param sock        the socket to read the request from
   *
   * @return a byte buffer holding the request, backed by an array.
   *         The request begins at the current position and
   *         extends to the limit of the buffer.
   *         This value is a suitable parameter for {@link #handleRequest}.
   *
   * @throws Exception  in case of a problem
   */
Reads a request from a socket and returns it.
@param sock        the socket to read the request from

@return a byte buffer holding the request, backed by an array.
The request begins at the current position and
extends to the limit of the buffer.
This value is a suitable parameter for  #handleRequest.

@throws Exception  in case of a problem
Reads a request from a socket and returns it . @param sock the socket to read the request from @return a byte buffer holding the request backed by an array . The request begins at the current position and extends to the limit of the buffer . This value is a suitable parameter for #handleRequest . @throws Exception in case of a problem
public ByteBuffer readRequest(Socket sock)
    throws Exception
  {
    sock.setSoTimeout(RCV_SO_TIMEOUT);
    final long started = System.currentTimeMillis();
    final long deadline = started + RCV_DEADLINE;
    byte[] data = new byte[MAX_REQUEST_SIZE];
    InputStream is = sock.getInputStream();
    int pos = is.read(data, 0, 4);
    if (pos < 4)
     {
       throw cancelRequest
         (Catalog.RECEIVE_INITIAL_BLOCK_TOO_SMALL_0.format(), null, sock);
     }
    if ((data[0] & 0xe0) != 0xe0) 
     {
       throw cancelRequest(Catalog.RECEIVE_BAD_TYPE_1
                           .format("0x"+Integer.toHexString(data[0] & 0xff)),
                           null, sock);
     }
    if (data[1] != MsgBoardTLV.LENGTH_OF_LENGTH_2)
     {
       throw cancelRequest(Catalog.RECEIVE_BAD_LEN_OF_LEN_1
                           .format("0x"+Integer.toHexString(data[1] & 0xff)),
                           null, sock);
     }
    int length = ((data[2] & 0xff)<<8) + (data[3] & 0xff);
    int size = length+4;
    if (size > MAX_REQUEST_SIZE)
     {
       throw cancelRequest(Catalog.RECEIVE_TOO_LONG_2
                           .format(length, MAX_REQUEST_SIZE), null, sock);
     }
    while (pos < size)
     {
       if (System.currentTimeMillis() > deadline)
        {
          throw cancelRequest
            (Catalog.RECEIVE_DEADLINE_EXPIRED_0.format(), null, sock);
        }
       int count = is.read(data, pos, data.length-pos);
       if (count < 0)
        {
          throw cancelRequest
            (Catalog.RECEIVE_INCOMPLETE_0.format(), null, sock);
        }
       pos += count;
     }
    final long ended = System.currentTimeMillis();
    ByteBuffer request = ByteBuffer.wrap(data, 0, size);
    return request;
  }
public ByteBuffer readRequest ( Socket sock ) throws Exception { sock . setSoTimeout ( RCV_SO_TIMEOUT ) ; final long started = System . currentTimeMillis ( ) ; final long deadline = started + RCV_DEADLINE ; byte [ ] data = new byte [ MAX_REQUEST_SIZE ] ; InputStream is = sock . getInputStream ( ) ; int pos = is . read ( data , 0 , 4 ) ; if ( pos < 4 ) { throw cancelRequest ( Catalog . RECEIVE_INITIAL_BLOCK_TOO_SMALL_0 . format ( ) , null , sock ) ; } if ( ( data [ 0 ] & 0xe0 ) != 0xe0 ) { throw cancelRequest ( Catalog . RECEIVE_BAD_TYPE_1 . format ( "0x" + Integer . toHexString ( data [ 0 ] & 0xff ) ) , null , sock ) ; } if ( data [ 1 ] != MsgBoardTLV . LENGTH_OF_LENGTH_2 ) { throw cancelRequest ( Catalog . RECEIVE_BAD_LEN_OF_LEN_1 . format ( "0x" + Integer . toHexString ( data [ 1 ] & 0xff ) ) , null , sock ) ; } int length = ( ( data [ 2 ] & 0xff ) << 8 ) + ( data [ 3 ] & 0xff ) ; int size = length + 4 ; if ( size > MAX_REQUEST_SIZE ) { throw cancelRequest ( Catalog . RECEIVE_TOO_LONG_2 . format ( length , MAX_REQUEST_SIZE ) , null , sock ) ; } while ( pos < size ) { if ( System . currentTimeMillis ( ) > deadline ) { throw cancelRequest ( Catalog . RECEIVE_DEADLINE_EXPIRED_0 . format ( ) , null , sock ) ; } int count = is . read ( data , pos , data . length - pos ) ; if ( count < 0 ) { throw cancelRequest ( Catalog . RECEIVE_INCOMPLETE_0 . format ( ) , null , sock ) ; } pos += count ; } final long ended = System . currentTimeMillis ( ) ; ByteBuffer request = ByteBuffer . wrap ( data , 0 , size ) ; return request ; }
Reads a request from a socket and returns it.
Reads a request from a socket and returns it .
// to avoid permanent blocking by misbehaving clients: // - set a timeout on the socket // - track how long it takes to receive the request, cancel if necessary //   The client could send byte by byte to avoid timeouts. //@@@ This logic is specific to TLVs; also needed by clients... refactor! //@@@ Send error response to bogus request, or just drop the connection? // Read the first 4 bytes of data, expected in first block of data. // Clients that try to send data byte for byte will be kicked out. // Requests are in TLV format, see ASN.1 BER // byte 1: type of the request // byte 2: length of length, value 0x82 indicating 2 bytes for the length // byte 3: upper byte of length // byte 4: lower byte of length // expect bits: 111xxxx //System.out.println("received request of "+(length+4)+ //                    " bytes in "+(ended-started)+" ms");