@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();
    }
  }
 private void addDataToSend(
     Session session, ChannelType target, byte[] originalData, boolean needEncryption) {
   byte[] dataToSend = originalData;
   if (needEncryption) {
     dataToSend = handleDataEncryption(session.getEncryptor(), target, originalData);
   }
   ChannelData channelData = session.getData(target);
   if (channelData == null) {
     throw new NullPointerException();
   }
   channelData.addDataToSend(dataToSend);
   ShadowsocksLocal.getInstance().addEvent(new WriteEvent(session, target));
 }