protected Commutable receiveData(Connection conn, Connection nextConn) throws Exception {
   InputStream in = conn.getInputDtream();
   OutputStream outNextWorker = null;
   if (nextConn != null) {
     outNextWorker = nextConn.getOutputStream();
   }
   // Receive data
   ByteArray byteArray = receiveByteArray(in, outNextWorker);
   // Close connection
   conn.close();
   if (nextConn != null) {
     nextConn.close();
   }
   // Process byte array
   Commutable data = null;
   try {
     data = processByteArray(byteArray);
   } catch (Exception e) {
     releaseBytes(byteArray.getArray());
     releaseInts(byteArray.getMetaArray());
     throw e;
   }
   return data;
 }
 /**
  * Receive 1. command 2. byte array size 3. meta data size 4. meta data content
  *
  * @param in
  * @param outNextWorker
  * @return
  * @throws Exception
  */
 private ByteArray receiveByteArray(InputStream in, OutputStream outNextWorker) throws Exception {
   // int size = din.readInt();
   // int metaDataSize = din.readInt();
   // Read byte array size and meta array size
   byte[] sizeBytes = this.getResourcePool().getByteArrayPool().getArray(8);
   in.read(sizeBytes);
   // Forward
   if (outNextWorker != null) {
     outNextWorker.write(this.getCommand());
     outNextWorker.write(sizeBytes);
   }
   DataDeserializer deserializer = new DataDeserializer(sizeBytes);
   int size = deserializer.readInt();
   int metaArraySize = deserializer.readInt();
   this.getResourcePool().getByteArrayPool().releaseArrayInUse(sizeBytes);
   // Read meta array
   int[] metaArray = null;
   if (metaArraySize > 0) {
     metaArray = this.getResourcePool().getIntArrayPool().getArray(metaArraySize);
     byte[] metaArrayBytes = this.getResourcePool().getByteArrayPool().getArray(4 * metaArraySize);
     in.read(metaArrayBytes);
     // Forward
     if (outNextWorker != null) {
       outNextWorker.write(metaArrayBytes);
     }
     deserializer.setData(metaArrayBytes);
     for (int i = 0; i < metaArraySize; i++) {
       metaArray[i] = deserializer.readInt();
     }
     this.getResourcePool().getByteArrayPool().releaseArrayInUse(metaArrayBytes);
   }
   if (outNextWorker != null) {
     outNextWorker.flush();
   }
   // Prepare internal bytes structure
   byte[] bytes =
       this.getResourcePool().getByteArrayPool().getArray(size + Constants.SENDRECV_BYTE_UNIT);
   try {
     receiveBytes(in, outNextWorker, bytes, size);
   } catch (Exception e) {
     releaseBytes(bytes);
     releaseInts(metaArray);
     throw e;
   }
   ByteArray byteArray = new ByteArray();
   byteArray.setArray(bytes);
   byteArray.setStart(0);
   byteArray.setSize(size);
   byteArray.setMetaArray(metaArray);
   byteArray.setMetaArraySize(metaArraySize);
   return byteArray;
 }