src/main/java/pityoulish/sockets/client/MsgBoardClientHandlerImpl.java
public ByteBuffer readResponse(Socket sock)
    throws Exception
  {
    sock.setSoTimeout(RCV_SO_TIMEOUT);

    byte[] data = new byte[MAX_RESPONSE_SIZE];
    int    pos  = 0;

    if (beVerbose)
       System.out.println(Catalog.INFO_RECEIVING_0.format());

    InputStream is = sock.getInputStream();

    //@@@ This logic is specific to TLVs... move it elsewhere.
    //@@@ It's the same as in the server, so move to a shared package.
    //@@@ Not to ...tlv though, because the interface is not TLV-specific.

    // need the first 4 bytes to determine the length of the response
    while (pos < 4)
     {
       int count = is.read(data, pos, data.length-pos);
       if (count < 0)
          throw new Exception
            (Catalog.RECEIVE_INITIAL_BLOCK_TOO_SMALL_0.format());
       pos += count;
     }

    if ((data[0] == 'H') &&
        (data[1] == 'T') &&
        (data[2] == 'T') &&
        (data[3] == 'P') ) {
      // happens often enough to merit a dedicated check and error message
      throw new Exception(Catalog.RECEIVE_HTTP_INSTEAD_OF_TLV_0.format());
    }

    // Responses are in TLV format, see ASN.1 BER
    // byte 1: type of the response
    // 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 new Exception
         (Catalog.RECEIVE_BAD_TYPE_1.format
          ("0x"+Integer.toHexString(data[0] & 0xff)));

    if (data[1] != MsgBoardTLV.LENGTH_OF_LENGTH_2)
       throw new Exception
         (Catalog.RECEIVE_BAD_LEN_OF_LEN_1.format
          ("0x"+Integer.toHexString(data[1] & 0xff)));

    int length = ((data[2] & 0xff)<<8) + (data[3] & 0xff);
    int size = length+4;
    if (size > MAX_RESPONSE_SIZE)
     {
       // Technically, the TLV response could be up to 65539 bytes long.
       // But it's not uncommon to define a sanity limit on message sizes.
       throw new Exception
         (Catalog.RECEIVE_TOO_LONG_2.format(length, MAX_RESPONSE_SIZE));
     }

    while (pos < size)
     {
       if (beVerbose)
          System.out.println(Catalog.INFO_STILL_MISSING_1.format(size-pos));

       int count = is.read(data, pos, data.length-pos);
       if (count < 0)
          throw new Exception(Catalog.RECEIVE_INCOMPLETE_0.format());
       pos += count;
     }

    if (pos > size)
     {
       // Expect exactly one TLV as response, nothing more.
       // Technically, the TLV response could be up to 65539 bytes long.
       // But it's not uncommon to define a sanity limit on message sizes.
       throw new Exception(Catalog.RECEIVE_EXCESS_DATA_2.format(pos, size));
     }

    if (beVerbose)
       System.out.println(Catalog.INFO_RESPONSE_RECEIVED_1.format(size));

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

  }
/**
   * Reads a response from a socket and returns it.
   *
   * @param sock        the socket to read the response from
   *
   * @return a byte buffer holding the response, backed by an array.
   *         The response begins at the current position and
   *         extends to the limit of the buffer.
   *
   * @throws Exception  in case of a problem
   */
Reads a response from a socket and returns it.
@param sock        the socket to read the response from

@return a byte buffer holding the response, backed by an array.
The response begins at the current position and
extends to the limit of the buffer.

@throws Exception  in case of a problem
Reads a response from a socket and returns it . @param sock the socket to read the response from @return a byte buffer holding the response backed by an array . The response begins at the current position and extends to the limit of the buffer . @throws Exception in case of a problem
public ByteBuffer readResponse(Socket sock)
    throws Exception
  {
    sock.setSoTimeout(RCV_SO_TIMEOUT);
    byte[] data = new byte[MAX_RESPONSE_SIZE];
    int    pos  = 0;
    if (beVerbose)
       System.out.println(Catalog.INFO_RECEIVING_0.format());
    InputStream is = sock.getInputStream();
    while (pos < 4)
     {
       int count = is.read(data, pos, data.length-pos);
       if (count < 0)
          throw new Exception
            (Catalog.RECEIVE_INITIAL_BLOCK_TOO_SMALL_0.format());
       pos += count;
     }
    if ((data[0] == 'H') &&
        (data[1] == 'T') &&
        (data[2] == 'T') &&
        (data[3] == 'P') ) {
      throw new Exception(Catalog.RECEIVE_HTTP_INSTEAD_OF_TLV_0.format());
    }
    if ((data[0] & 0xe0) != 0xe0) 
       throw new Exception
         (Catalog.RECEIVE_BAD_TYPE_1.format
          ("0x"+Integer.toHexString(data[0] & 0xff)));
    if (data[1] != MsgBoardTLV.LENGTH_OF_LENGTH_2)
       throw new Exception
         (Catalog.RECEIVE_BAD_LEN_OF_LEN_1.format
          ("0x"+Integer.toHexString(data[1] & 0xff)));
    int length = ((data[2] & 0xff)<<8) + (data[3] & 0xff);
    int size = length+4;
    if (size > MAX_RESPONSE_SIZE)
     {
       throw new Exception
         (Catalog.RECEIVE_TOO_LONG_2.format(length, MAX_RESPONSE_SIZE));
     }
    while (pos < size)
     {
       if (beVerbose)
          System.out.println(Catalog.INFO_STILL_MISSING_1.format(size-pos));
       int count = is.read(data, pos, data.length-pos);
       if (count < 0)
          throw new Exception(Catalog.RECEIVE_INCOMPLETE_0.format());
       pos += count;
     }
    if (pos > size)
     {
       throw new Exception(Catalog.RECEIVE_EXCESS_DATA_2.format(pos, size));
     }
    if (beVerbose)
       System.out.println(Catalog.INFO_RESPONSE_RECEIVED_1.format(size));
    ByteBuffer response = ByteBuffer.wrap(data, 0, size);
    return response;
  }
public ByteBuffer readResponse ( Socket sock ) throws Exception { sock . setSoTimeout ( RCV_SO_TIMEOUT ) ; byte [ ] data = new byte [ MAX_RESPONSE_SIZE ] ; int pos = 0 ; if ( beVerbose ) System . out . println ( Catalog . INFO_RECEIVING_0 . format ( ) ) ; InputStream is = sock . getInputStream ( ) ; while ( pos < 4 ) { int count = is . read ( data , pos , data . length - pos ) ; if ( count < 0 ) throw new Exception ( Catalog . RECEIVE_INITIAL_BLOCK_TOO_SMALL_0 . format ( ) ) ; pos += count ; } if ( ( data [ 0 ] == 'H' ) && ( data [ 1 ] == 'T' ) && ( data [ 2 ] == 'T' ) && ( data [ 3 ] == 'P' ) ) { throw new Exception ( Catalog . RECEIVE_HTTP_INSTEAD_OF_TLV_0 . format ( ) ) ; } if ( ( data [ 0 ] & 0xe0 ) != 0xe0 ) throw new Exception ( Catalog . RECEIVE_BAD_TYPE_1 . format ( "0x" + Integer . toHexString ( data [ 0 ] & 0xff ) ) ) ; if ( data [ 1 ] != MsgBoardTLV . LENGTH_OF_LENGTH_2 ) throw new Exception ( Catalog . RECEIVE_BAD_LEN_OF_LEN_1 . format ( "0x" + Integer . toHexString ( data [ 1 ] & 0xff ) ) ) ; int length = ( ( data [ 2 ] & 0xff ) << 8 ) + ( data [ 3 ] & 0xff ) ; int size = length + 4 ; if ( size > MAX_RESPONSE_SIZE ) { throw new Exception ( Catalog . RECEIVE_TOO_LONG_2 . format ( length , MAX_RESPONSE_SIZE ) ) ; } while ( pos < size ) { if ( beVerbose ) System . out . println ( Catalog . INFO_STILL_MISSING_1 . format ( size - pos ) ) ; int count = is . read ( data , pos , data . length - pos ) ; if ( count < 0 ) throw new Exception ( Catalog . RECEIVE_INCOMPLETE_0 . format ( ) ) ; pos += count ; } if ( pos > size ) { throw new Exception ( Catalog . RECEIVE_EXCESS_DATA_2 . format ( pos , size ) ) ; } if ( beVerbose ) System . out . println ( Catalog . INFO_RESPONSE_RECEIVED_1 . format ( size ) ) ; ByteBuffer response = ByteBuffer . wrap ( data , 0 , size ) ; return response ; }
Reads a response from a socket and returns it.
Reads a response from a socket and returns it .
//@@@ This logic is specific to TLVs... move it elsewhere. //@@@ It's the same as in the server, so move to a shared package. //@@@ Not to ...tlv though, because the interface is not TLV-specific. // need the first 4 bytes to determine the length of the response // happens often enough to merit a dedicated check and error message // Responses are in TLV format, see ASN.1 BER // byte 1: type of the response // 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 // Technically, the TLV response could be up to 65539 bytes long. // But it's not uncommon to define a sanity limit on message sizes. // Expect exactly one TLV as response, nothing more. // Technically, the TLV response could be up to 65539 bytes long. // But it's not uncommon to define a sanity limit on message sizes.