private void handleReads(SelectionKey sk, MemcachedNode qa) throws IOException {
   Operation currentOp = qa.getCurrentReadOp();
   ByteBuffer rbuf = qa.getRbuf();
   final SocketChannel channel = qa.getChannel();
   int read = channel.read(rbuf);
   while (read > 0) {
     getLogger().debug("Read %d bytes", read);
     rbuf.flip();
     while (rbuf.remaining() > 0) {
       assert currentOp != null : "No read operation";
       currentOp.readFromBuffer(rbuf);
       if (currentOp.getState() == OperationState.COMPLETE) {
         getLogger()
             .debug(
                 "Completed read op: %s and giving the next %d bytes",
                 currentOp, rbuf.remaining());
         Operation op = qa.removeCurrentReadOp();
         assert op == currentOp : "Expected to pop " + currentOp + " got " + op;
         currentOp = qa.getCurrentReadOp();
       }
     }
     rbuf.clear();
     read = channel.read(rbuf);
   }
 }
  public Object readObject(Connection connection) throws IOException {
    SocketChannel socketChannel = this.socketChannel;
    if (socketChannel == null) throw new SocketException("Connection is closed.");

    if (currentObjectLength == 0) {
      // Read the length of the next object from the socket.
      int lengthLength = serialization.getLengthLength();
      if (readBuffer.remaining() < lengthLength) {
        readBuffer.compact();
        int bytesRead = socketChannel.read(readBuffer);
        readBuffer.flip();
        if (bytesRead == -1) throw new SocketException("Connection is closed.");
        lastReadTime = System.currentTimeMillis();

        if (readBuffer.remaining() < lengthLength) return null;
      }
      currentObjectLength = serialization.readLength(readBuffer);

      if (currentObjectLength <= 0)
        throw new KryoNetException("Invalid object length: " + currentObjectLength);
      if (currentObjectLength > readBuffer.capacity())
        throw new KryoNetException(
            "Unable to read object larger than read buffer: " + currentObjectLength);
    }

    int length = currentObjectLength;
    if (readBuffer.remaining() < length) {
      // Fill the tcpInputStream.
      readBuffer.compact();
      int bytesRead = socketChannel.read(readBuffer);
      readBuffer.flip();
      if (bytesRead == -1) throw new SocketException("Connection is closed.");
      lastReadTime = System.currentTimeMillis();

      if (readBuffer.remaining() < length) return null;
    }
    currentObjectLength = 0;

    int startPosition = readBuffer.position();
    int oldLimit = readBuffer.limit();
    readBuffer.limit(startPosition + length);
    Object object;
    try {
      object = serialization.read(connection, readBuffer);
    } catch (Exception ex) {
      throw new KryoNetException("Error during deserialization.", ex);
    }

    readBuffer.limit(oldLimit);
    if (readBuffer.position() - startPosition != length)
      throw new KryoNetException(
          "Incorrect number of bytes ("
              + (startPosition + length - readBuffer.position())
              + " remaining) used to deserialize object: "
              + object);

    return object;
  }
Example #3
0
  @Test
  public void testGentleCloseDuringHandshake() throws Exception {
    InetSocketAddress address = startServer(version, null);
    SslContextFactory sslContextFactory = newSslContextFactory();
    sslContextFactory.start();
    SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
    sslEngine.setUseClientMode(true);
    NextProtoNego.put(
        sslEngine,
        new NextProtoNego.ClientProvider() {
          @Override
          public boolean supports() {
            return true;
          }

          @Override
          public void unsupported() {}

          @Override
          public String selectProtocol(List<String> protocols) {
            return null;
          }
        });
    sslEngine.beginHandshake();

    ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
    sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
    encrypted.flip();

    try (SocketChannel channel = SocketChannel.open(address)) {
      // Send ClientHello, immediately followed by TLS Close Alert and then by FIN
      channel.write(encrypted);
      sslEngine.closeOutbound();
      encrypted.clear();
      sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
      encrypted.flip();
      channel.write(encrypted);
      channel.shutdownOutput();

      // Read ServerHello from server
      encrypted.clear();
      int read = channel.read(encrypted);
      encrypted.flip();
      Assert.assertTrue(read > 0);
      // Cannot decrypt, as the SSLEngine has been already closed

      // Now if we read more, we should either read the TLS Close Alert, or directly -1
      encrypted.clear();
      read = channel.read(encrypted);
      // Sending a TLS Close Alert during handshake results in an exception when
      // unwrapping that the server react to by closing the connection abruptly.
      Assert.assertTrue(read < 0);
    }
  }
  public byte[] handleRead() throws IOException {
    boolean find = false;
    int index = 0;
    if (state == READING_LENGTH) {
      int nbread = sock.read(lenBuf);
      if (nbread == -1) {
        // Error of reading bytes, so close the socket to prevent other error
        sock.close();
        connectionClosed = true;
        return null;
      }
      if (lenBuf.remaining() == 0) {
        // Read the length
        int length = Util.readInt32(lenBuf.array(), 0);
        int size = buffers.size();
        for (int i = 0; i < size; i++) {
          if (buffers.get(i).capacity() == length) {
            find = true;
            index = i;
          }
        }
        if (find) {
          msgBuf = buffers.get(index);
          // System.out.println("buffer with a right size found");
        } else {
          try {
            msgBuf = ByteBuffer.allocate(length);
            buffers.add(msgBuf);
          } catch (OutOfMemoryError e) {
            System.err.println(e);
            sock.close();
            connectionClosed = true;
            return null;
          }
          // System.out.println("No buffer found : length : " + length);
        }
        msgBuf.clear();
        lenBuf = (ByteBuffer) lenBuf.position(0);
        state = READING_MSG;
      }
    }

    if (state == READING_MSG) {
      sock.read(msgBuf);
      if (msgBuf.remaining() == 0) { // the message has been fully received
        // deliver it"
        byte[] msg = msgBuf.array();
        state = READING_LENGTH;
        return msg;
      }
    }
    return null;
  }
Example #5
0
  @Test
  public void testAbruptCloseDuringHandshake() throws Exception {
    InetSocketAddress address = startServer(version, null);
    SslContextFactory sslContextFactory = newSslContextFactory();
    sslContextFactory.start();
    SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
    sslEngine.setUseClientMode(true);
    NextProtoNego.put(
        sslEngine,
        new NextProtoNego.ClientProvider() {
          @Override
          public boolean supports() {
            return true;
          }

          @Override
          public void unsupported() {}

          @Override
          public String selectProtocol(List<String> protocols) {
            return null;
          }
        });
    sslEngine.beginHandshake();

    ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
    sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
    encrypted.flip();

    try (SocketChannel channel = SocketChannel.open(address)) {
      // Send ClientHello, immediately followed by FIN (no TLS Close Alert)
      channel.write(encrypted);
      channel.shutdownOutput();

      // Read ServerHello from server
      encrypted.clear();
      int read = channel.read(encrypted);
      encrypted.flip();
      Assert.assertTrue(read > 0);
      ByteBuffer decrypted = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize());
      sslEngine.unwrap(encrypted, decrypted);

      // Now if we read more, we should either read the TLS Close Alert, or directly -1
      encrypted.clear();
      read = channel.read(encrypted);
      // Since we have close the connection abruptly, the server also does so
      Assert.assertTrue(read < 0);
    }
  }
Example #6
0
  private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();

    // Clear out our read buffer so it's ready for new data
    this.readBuffer.clear();

    // Attempt to read off the channel
    int numRead;
    try {
      numRead = socketChannel.read(this.readBuffer);
    } catch (IOException e) {
      // The remote forcibly closed the connection, cancel
      // the selection key and close the channel.
      key.cancel();
      socketChannel.close();
      return;
    }

    if (numRead == -1) {
      // Remote entity shut the socket down cleanly. Do the
      // same from our end and cancel the channel.
      key.channel().close();
      key.cancel();
      return;
    }

    // Hand the data off to our worker thread
    this.worker.processData(this, socketChannel, this.readBuffer.array(), numRead);
  }
    /**
     * reads from the socket and writes them to the buffer
     *
     * @param socketChannel the socketChannel to read from
     * @return the number of bytes read
     * @throws IOException
     */
    private int readSocketToBuffer(@NotNull final SocketChannel socketChannel) throws IOException {

      compactBuffer();
      final int len = socketChannel.read(in);
      out.limit(in.position());
      return len;
    }
Example #8
0
 /**
  * 读取信息
  *
  * @param key
  * @return
  * @throws IOException
  */
 public byte[] readMessage(SelectionKey key) throws IOException {
   SocketChannel socketChannelForClient = (SocketChannel) key.channel();
   ByteBuffer byteBufferTemp = ByteBuffer.allocate(BUFFER_SIZE);
   socketChannelForClient.read(byteBufferTemp);
   byteBufferTemp.flip();
   return byteBufferTemp.array();
 }
  public void actionHandler(SelectionKey key) throws IOException {
    if (key.isAcceptable()) {
      ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
      SocketChannel socketChannel = serverChannel.accept();
      socketChannel.configureBlocking(false);
      socketChannel.register(roller, SelectionKey.OP_READ);
    } else if (key.isReadable()) {
      ByteBuffer buffer = ByteBuffer.allocate(16);
      SocketChannel socketChannel = (SocketChannel) key.channel();
      socketChannel.read(buffer);
      buffer.flip();
      String temp = decode(buffer);
      StringBuffer strBuffer = stringLocal.get();
      if (strBuffer == null) {
        strBuffer = new StringBuffer();
      }

      strBuffer.append(temp);

      if (temp.equals("\r\n")) {
        System.out.println(strBuffer.toString());
        strBuffer = null;
      }
      stringLocal.set(strBuffer);
    }
  }
Example #10
0
  private void handleInput(SelectionKey key) throws IOException {

    if (key != null && key.isValid()) {

      SocketChannel sc = (SocketChannel) key.channel();
      if (key.isConnectable()) {
        if (sc.finishConnect()) {
          sc.register(selector, SelectionKey.OP_READ);
          doWrite(sc);
        } else System.exit(1);
      }

      if (key.isReadable()) {
        ByteBuffer readBuffer = ByteBuffer.allocate(1024);
        int readBytes = sc.read(readBuffer);
        if (readBytes > 0) {
          readBuffer.flip();
          byte[] bytes = new byte[readBuffer.remaining()];
          readBuffer.get(bytes);
          String body = new String(bytes, "UTF-8");
          System.out.println("Now is : " + body);
          this.stop = true;
        } else if (readBytes < 0) {
          key.cancel();
          sc.close();
        } else {

        }
      }
    }
  }
Example #11
0
  private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();

    // Clear out our read buffer so it's ready for new data
    readBuffer.clear();

    // Attempt to read off the channel
    int numRead;
    try {
      numRead = socketChannel.read(readBuffer);
    } catch (IOException e) {
      key.cancel();
      socketChannel.close();

      System.out.println("Forceful shutdown");
      return;
    }

    if (numRead == -1) {
      System.out.println("Graceful shutdown");
      key.channel().close();
      key.cancel();

      return;
    }

    socketChannel.register(selector, SelectionKey.OP_WRITE);

    numMessages++;
    if (numMessages % 100000 == 0) {
      long elapsed = System.currentTimeMillis() - loopTime;
      loopTime = System.currentTimeMillis();
      System.out.println(elapsed);
    }
  }
  /**
   * Reads incoming data from the client:
   *
   * <UL>
   *   <LI>Reads some bytes from the SocketChannel
   *   <LI>create a protocolTask, to process this data, possibly generating an answer
   *   <LI>Inserts the Task to the ThreadPool
   * </UL>
   *
   * @throws
   * @throws IOException in case of an IOException during reading
   */
  public void read() {
    // do not read if OLD.protocol has terminated. only write of pending data is
    // allowed
    if (_protocol.shouldClose()) {
      return;
    }

    SocketAddress address = _sChannel.socket().getRemoteSocketAddress();
    logger.info("Reading from " + address);

    ByteBuffer buf = ByteBuffer.allocate(BUFFER_SIZE);
    int numBytesRead = 0;
    try {
      numBytesRead = _sChannel.read(buf);
    } catch (IOException e) {
      numBytesRead = -1;
    }
    // is the channel closed??
    if (numBytesRead == -1) {
      // No more bytes can be read from the channel
      logger.info("client on " + address + " has disconnected");
      closeConnection();
      // tell the OLD.protocol that the connection terminated.
      _protocol.connectionTerminated();
      return;
    }

    // add the buffer to the OLD.protocol task
    buf.flip();
    _task.addBytes(buf);
    // add the OLD.protocol task to the OLD.reactor
    _data.getExecutor().execute(_task);
  }
Example #13
0
 /*
  * Resize (if necessary) the inbound data buffer, and then read more
  * data into the read buffer.
  */
 int read() throws IOException {
   /*
    * Allocate more space if less than 5% remains
    */
   resizeRequestBB(requestBBSize / 20);
   return sc.read(requestBB);
 }
Example #14
0
  private void handle(SelectionKey key) throws IOException {
    // TODO Auto-generated method stub

    ServerSocketChannel server = null;
    SocketChannel client = null;
    String receiveText = null;
    int count = 0;

    if (key.isAcceptable()) {
      // client require accept events
      server = (ServerSocketChannel) key.channel();
      client = server.accept();
      client.configureBlocking(false);
      client.register(selector, SelectionKey.OP_READ);
    } else if (key.isReadable()) {
      // 如果是read事件,则直接读取
      client = (SocketChannel) key.channel();
      recBuffer.clear();
      count = client.read(recBuffer);
      if (count > 0) {
        recBuffer.flip();
        receiveText = decode.decode(recBuffer.asReadOnlyBuffer()).toString();
        System.out.println(client.toString() + ":" + receiveText);
        sendBuffer.clear();
        sendBuffer.put((sdf.format(new Date()) + "服务器收到你的消息").getBytes());
        sendBuffer.flip();
        client.write(sendBuffer);
        dispatch(client, receiveText);
        client = (SocketChannel) key.channel();
        client.register(selector, SelectionKey.OP_READ);
      }
    }
  }
Example #15
0
    private void processReads(Context cx) {
      if (!readStarted) {
        return;
      }
      int read;
      do {
        try {
          read = clientChannel.read(readBuffer);
        } catch (IOException ioe) {
          if (log.isDebugEnabled()) {
            log.debug("Error reading from channel: {}", ioe, ioe);
          }
          read = -1;
        }
        if (log.isDebugEnabled()) {
          log.debug("Read {} bytes from {} into {}", read, clientChannel, readBuffer);
        }
        if (read > 0) {
          readBuffer.flip();
          Buffer.BufferImpl buf = Buffer.BufferImpl.newBuffer(cx, this, readBuffer, true);
          readBuffer.clear();

          if (onRead != null) {
            onRead.call(cx, onRead, this, new Object[] {buf, 0, read});
          }
        } else if (read < 0) {
          setErrno(Constants.EOF);
          removeInterest(SelectionKey.OP_READ);
          if (onRead != null) {
            onRead.call(cx, onRead, this, new Object[] {null, 0, 0});
          }
        }
      } while (readStarted && (read > 0));
    }
Example #16
0
 private boolean _isOpenImpl() throws IOException {
   boolean wasBlocking = socketChannel.isBlocking();
   ByteBuffer buffer = ByteBuffer.allocate(1);
   if (wasBlocking) {
     socketChannel.configureBlocking(false);
   }
   int read;
   try {
     read = socketChannel.read(buffer);
   } catch (IOException e) {
     /* This should never happen in non Windows systems.
      * In Windows systems an IOException is thrown
      * whenever a client has closed its output connection
      * towards this channel and this method is called by
      * CommCore.
      */
     return false;
   }
   if (wasBlocking) {
     socketChannel.configureBlocking(true);
   }
   if (read == -1) {
     return false;
   } else if (read > 0) {
     istream.append(buffer.get(0));
   }
   return true;
 }
  /**
   * Reads bytes from the socket.
   *
   * @param buf byte buffer receiving the bytes
   * @param offset offset into the buffer
   * @param length number of bytes to read
   * @return number of bytes read or -1
   * @exception throws ClientDisconnectException if the connection is dropped
   */
  @Override
  public int read(byte[] buf, int offset, int length) throws IOException {
    try {
      SocketChannel s = _s;

      if (s == null) {
        return -1;
      }

      int remaining = _readBuffer.remaining();
      if (remaining <= 0) {
        _readBuffer.clear();

        if (s.read(_readBuffer) < 0) {
          _readBuffer.flip();
          return -1;
        }

        _readBuffer.flip();

        remaining = _readBuffer.remaining();
      }

      int sublen = Math.min(remaining, length);

      _readBuffer.get(buf, offset, sublen);

      int readLength = sublen;

      if (readLength >= 0) {
        _totalReadBytes += readLength;
      }

      return readLength;
    } catch (InterruptedIOException e) {
      if (_throwReadInterrupts) throw e;

      log.log(Level.FINEST, e.toString(), e);
    } catch (IOException e) {
      if (_throwReadInterrupts) {
        throw e;
      }

      if (log.isLoggable(Level.FINEST)) {
        log.log(Level.FINEST, e.toString(), e);
      } else {
        log.finer(e.toString());
      }
      // server/0611
      /*
      try {
        close();
      } catch (IOException e1) {
      }
      */
    }

    return -1;
  }
  protected static void readData(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    buffer.flip();
    int count = socketChannel.read(buffer);
    while (count > 0) {
      while (buffer.hasRemaining()) {
        //                socketChannel.write(buffer);
        System.out.print((char) buffer.get());
      }

      buffer.clear();
      count = socketChannel.read(buffer);
      if (count < 0) {
        socketChannel.close();
      }
    }
  }
Example #19
0
 private void read(SocketChannel channel, ByteBuffer buffer) throws IOException {
   while (buffer.hasRemaining()) {
     int r = channel.read(buffer);
     if (r == -1) {
       throw new IOException("end of stream when reading header");
     }
   }
 }
 private long readIndex(SocketChannel socket) throws IOException {
   ByteBuffer bb = ByteBuffer.allocate(8);
   while (bb.remaining() > 0 && socket.read(bb) > 0) {
     doNothing();
   }
   if (bb.remaining() > 0) throw new EOFException();
   return bb.getLong(0);
 }
Example #21
0
 private int readInt(SocketChannel socketChannel) throws IOException {
   ByteBuffer buffer = ByteBuffer.allocate(4);
   while (buffer.hasRemaining()) {
     socketChannel.read(buffer);
   }
   buffer.flip();
   return buffer.getInt();
 }
Example #22
0
 public int read(ByteBuffer dst) throws IOException {
   try {
     return sc.read(dst);
   } catch (AsynchronousCloseException x) {
     close();
     throw x;
   }
 }
Example #23
0
 /**
  * loops over read method until buffer has been filled. buffer size is equal to the parameter
  *
  * @param bytes the number of bytes to read from stream
  * @return Associated ByteBuffer that was filled
  */
 byte[] read(int bytes) throws IOException {
   b.clear();
   while (b.hasRemaining() && (bytes == b.capacity() - b.remaining())) {
     ssc.read(b);
   }
   b.flip();
   return b.array();
 }
Example #24
0
 /**
  * reads maximum of messageSize bytes, does not guarantee any number of bytes will be read
  *
  * @return Associated ByteBuffer that was filled
  */
 byte[] read() throws IOException {
   b.clear();
   ssc.read(b);
   b.flip();
   byte[] d = new byte[b.limit()];
   b.get(d, 0, b.limit());
   return d;
 }
Example #25
0
  private int read() throws IOException {
    //		System.out.println("Doing a read ");
    int count = 0;
    while ((count = channel.read(netRecvBuffer)) > 0) ;
    if (count == -1) throw new IOException("Connection closed");

    if (!isHanshakeDone) {
      if (!handleSSLHandshake2()) return 0;
      else {
        if (appSendBuffer.hasRemaining()) {
          channel.register(selector, SelectionKey.OP_WRITE);
          selector.wakeup();
          return 0;
        }
      }
    }

    int retval = 0;
    boolean loop = true;
    while (loop) {
      netRecvBuffer.flip();
      SSLEngineResult engineResult = engine.unwrap(netRecvBuffer, appRecvBuffer);
      netRecvBuffer.compact();

      switch (engineResult.getStatus()) {
        case BUFFER_UNDERFLOW: // There is not enough data read from the network buffer to do the
                               // handshaking
          // Setting the selector to be read again and pass 0 to the caller saying there is nothing
          // to read
          // System.out.println("Read buffer underflow");
          channel.register(selector, SelectionKey.OP_READ);
          selector.wakeup();
          loop = false;
          break;
        case BUFFER_OVERFLOW: // The appbuffer is full the caller really needs to read the current
                              // buffer.
          // Please not this not a problem in the our current implementation as we make sure we are
          // writing the data to the stream
          // System.out.println("Read buffer overflow");
          retval = appRecvBuffer.position();
          loop = false;
          break;
        case CLOSED:
          throw new IOException("Connection closed");
        case OK:
          retval = appRecvBuffer.position();
          break;
        default:
          break;
      }
      if (!handleSSLHandshake2()) {
        loop = false;
        retval = 0;
      }
    }
    return retval;
  }
  protected String sendAndReceive(byte[] payload) throws IOException {
    ByteBuffer sbuf = ByteBuffer.wrap(payload);
    ByteBuffer rbuf = ByteBuffer.allocateDirect(256);
    CharsetDecoder rbufDecoder = Charset.forName("UTF-8").newDecoder();
    StringBuilder response = new StringBuilder();

    int ops = SelectionKey.OP_WRITE | SelectionKey.OP_READ;
    if (this.channel.isConnectionPending()) {
      ops = ops | SelectionKey.OP_CONNECT;
    }

    Selector selector = Selector.open();
    try {
      this.channel.register(selector, ops);
      while (true) {
        if (0 < selector.select(Client.POLLS_INTERVAL * 1000)) {
          Iterator keys = selector.selectedKeys().iterator();
          while (keys.hasNext()) {
            SelectionKey key = (SelectionKey) keys.next();
            SocketChannel ch = (SocketChannel) key.channel();
            if (key.isConnectable()) {
              // Just connected
              ch.finishConnect();
            }
            if (key.isReadable() && !sbuf.hasRemaining()) {
              // Receiving the response
              while (0 < ch.read(rbuf)) {
                rbuf.flip();
                response.append(rbufDecoder.decode(rbuf).toString());
              }
              if (2 <= response.length()
                  && response
                      .substring(response.length() - 2, response.length())
                      .equals(SocketClient.TERMINATOR)) {
                response.setLength(response.length() - 2);
                return response.toString();
              } else if (0 == response.length()) {
                throw new IOException("Connection lost");
              }
            }
            if (key.isWritable() && sbuf.hasRemaining()) {
              // Sending the request
              while (0 < ch.write(sbuf) && sbuf.hasRemaining()) {
                //
              }
            }
            keys.remove();
          }
        }
      }
    } catch (java.lang.Exception e) {
      throw new IOException("API communication failed: " + e.toString());
    } finally {
      selector.close();
    }
  }
Example #27
0
  private int read(ByteBuffer buf) {
    int nbytes = 0;
    try {
      nbytes = handle.read(buf);
    } catch (IOException e) {
      return -1;
    }

    return nbytes;
  }
Example #28
0
 public void readOver() {
   try {
     buffer = ByteBuffer.allocateDirect(1024);
     while ((size = socketChannel.read(buffer)) >= 0) {
       buffer.clear();
     }
   } catch (Exception e) {
     log.info("read error");
   }
 }
  String read(final SocketChannel channel) throws IOException {
    StringBuilder result = new StringBuilder();

    int bytesRead = channel.read(readBuffer);
    while (bytesRead > 0) {
      readBuffer.rewind();
      bytesRead = channel.read(readBuffer);
      readBuffer.rewind();
      result.append(decoder.decode(readBuffer));
      readBuffer.clear();
    }

    if (bytesRead == -1) {
      selectionKey.cancel();
    }

    LOGGER.info(String.format("%s read done.", name));
    return result.toString();
  }
  @Override
  public void handle(ReadEvent event) {
    SelectionKey key = event.getKey();
    SocketChannel channel = (SocketChannel) key.channel();
    Session session = (Session) key.attachment();

    if (session.isClosed()) {
      return;
    }

    try {
      ChannelData data = session.getData(channel);
      ByteBuffer readBuffer = data.getReadBuffer();
      int size = channel.read(readBuffer);
      if (size < 0) {
        session.close();
        return;
      }

      readBuffer.flip();
      handleRead(session, data.getType(), data.getReadBuffer());
    } catch (Throwable t) {
      Logger.debug(t);
      session.close();
    }
  }