/**
  * Handle received selection keys.
  *
  * @param selectionKeys the selection keys.
  * @throws IOException
  */
 private void handleSelectionKeys(Set<SelectionKey> selectionKeys) throws IOException {
   if (CollectionUtils.isEmpty(selectionKeys)) {
     // nothing happened
     return;
   }
   int size = selectionKeys.size();
   this.logger.info("Handling [{}] selection keys", size);
   // something happened
   Iterator<SelectionKey> iterator = selectionKeys.iterator();
   while (iterator.hasNext()) {
     SelectionKey selectionKey = iterator.next();
     iterator.remove();
     this.logger.debug("Remaining [{}] selection keys", selectionKeys.size());
     // remove as to not process again.
     try {
       if (!selectionKey.isValid()) {
         continue;
       }
       SelectionKeyCommand selectionKeyCommand =
           this.selectionKeyCommandFactory.getSelectionKeyCommand(selectionKey);
       selectionKeyCommand.execute(selectionKey);
     } catch (Exception ex) {
       StringBuffer buffer = new StringBuffer("Error [");
       buffer.append(ex.getMessage());
       buffer.append("] on [");
       buffer.append(selectionKey.channel());
       buffer.append("] channel");
       this.logger.error(buffer.toString(), ex);
       SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
       socketChannel.close();
     }
   }
   this.logger.info("Handled [{}] selection keys", size);
 }
  /*
   * (non-Javadoc)
   *
   * @see java.lang.Runnable#run()
   */
  @Override
  public void run() {
    while (!stop) {
      try {
        selector.select(1000);
        Set<SelectionKey> selectedKeys = selector.selectedKeys();
        Iterator<SelectionKey> it = selectedKeys.iterator();
        SelectionKey key = null;
        while (it.hasNext()) {
          key = it.next();
          it.remove();
          try {
            handleInput(key);
          } catch (Exception e) {
            if (key != null) {
              key.cancel();
              if (key.channel() != null) key.channel().close();
            }
          }
        }
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }

    // 多路复用器关闭后,所有注册在上面的Channel和Pipe等资源都会被自动去注册并关闭,所以不需要重复释放资源
    if (selector != null)
      try {
        selector.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
  }
  private void listen() throws IOException {
    while (true) {
      int selec = selector.select(500);

      if (selec == 0) {
        continue;
      }

      Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();
      while (iterator.hasNext()) {
        SelectionKey selectionKey = iterator.next();
        try {
          iterator.remove();

          if (selectionKey.isAcceptable()) {
            ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel();
            SocketChannel sc = ssc.accept();
            sc.configureBlocking(false);

            sc.register(selector, SelectionKey.OP_READ);
          } else if (selectionKey.isReadable()) {
            read(selectionKey);
          } else if (selectionKey.isWritable()) {
            write(selectionKey);
          }
        } catch (Exception e) {
          // iterator.remove(); Don't use it! It can throw a exception!
          SocketChannel sc = (SocketChannel) selectionKey.channel();
          sc.close();
        }
      }
    }
  }
 public void serve(int port) throws IOException {
   ServerSocketChannel serverChannel = ServerSocketChannel.open();
   serverChannel.configureBlocking(false);
   ServerSocket ss = serverChannel.socket();
   InetSocketAddress address = new InetSocketAddress(port);
   // Binds the server to the selected port
   ss.bind(address);
   // Opens the Selector for handling channels
   Selector selector = Selector.open();
   // Registers the ServerSocket with the Selector to accept connections
   serverChannel.register(selector, SelectionKey.OP_ACCEPT);
   final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());
   while (true) {
     try {
       // Waits for new events to process; blocks until the next incoming event
       selector.select();
     } catch (IOException e) {
       e.printStackTrace();
       break;
     }
     // Obtains all SelectionKey instances that received events
     Set<SelectionKey> readyKeys = selector.selectedKeys();
     Iterator<SelectionKey> iterator = readyKeys.iterator();
     while (iterator.hasNext()) {
       SelectionKey key = iterator.next();
       iterator.remove();
       try {
         // Checks if the event is a new connection ready to be accepted
         if (key.isAcceptable()) {
           ServerSocketChannel server = (ServerSocketChannel) key.channel();
           SocketChannel client = server.accept();
           client.configureBlocking(false);
           // Accepts client and registers it with the selector
           client.register(
               selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, msg.duplicate());
           System.out.println("Accepted connection from " + client);
         }
         // Checks if the socket is ready for writing data
         if (key.isWritable()) {
           SocketChannel client = (SocketChannel) key.channel();
           ByteBuffer buffer = (ByteBuffer) key.attachment();
           while (buffer.hasRemaining()) {
             // Writes data to the connected client
             if (client.write(buffer) == 0) {
               break;
             }
           }
           // Closes the connection
           client.close();
         }
       } catch (IOException e) {
         key.cancel();
         try {
           key.channel().close();
         } catch (IOException e1) {
         }
       }
     }
   }
 }
Example #5
0
  private void write(SelectionKey key) {
    SocketChannel socketChannel = (SocketChannel) key.channel();

    DataServerMessage sendMessage = mSendingData.get(socketChannel);

    boolean closeChannel = false;
    try {
      sendMessage.send(socketChannel);
    } catch (IOException e) {
      closeChannel = true;
      LOG.error(e.getMessage());
    }

    if (sendMessage.finishSending() || closeChannel) {
      try {
        key.channel().close();
      } catch (IOException e) {
        LOG.error(e.getMessage());
      }
      key.cancel();
      mReceivingData.remove(socketChannel);
      mSendingData.remove(socketChannel);
      sendMessage.close();
      mBlocksLocker.unlock(Math.abs(sendMessage.getBlockId()), sendMessage.getLockId());
    }
  }
  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);
    }
  }
  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);
    }
  }
  private void processKey(SelectionKey key) {

    try {

      if (key.isReadable()) {
        final DatagramChannel socketChannel = (DatagramChannel) key.channel();
        reader.readAll(socketChannel);
      }

      if (key.isWritable()) {
        final DatagramChannel socketChannel = (DatagramChannel) key.channel();
        try {
          int bytesJustWritten = writer.writeAll(socketChannel);
          contemplateThrottleWrites(bytesJustWritten);
        } catch (NotYetConnectedException e) {
          if (LOG.isDebugEnabled()) LOG.debug("", e);
          serverConnector.connectLater();
        } catch (IOException e) {
          if (LOG.isDebugEnabled()) LOG.debug("", e);
          serverConnector.connectLater();
        }
      }
    } catch (Exception e) {
      LOG.error("", e);
      if (!isClosed) closeEarlyAndQuietly(key.channel());
    }
  }
Example #9
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);
      }
    }
  }
  void unregisterChannels(SelectionKeyRegistrationReference registrationReference)
      throws Exception {

    registrationReference.cancelRegistration();

    SelectorIntraband defaultIntraband = (SelectorIntraband) registrationReference.getIntraband();

    Selector selector = defaultIntraband.selector;

    Set<SelectionKey> keys = selector.keys();

    while (!keys.isEmpty()) {
      selector.wakeup();
    }

    SelectionKey readSelectionKey = registrationReference.readSelectionKey;
    SelectionKey writeSelectionKey = registrationReference.writeSelectionKey;

    SelectableChannel readSelectableChannel = readSelectionKey.channel();
    SelectableChannel writeSelectableChannel = writeSelectionKey.channel();

    while (readSelectableChannel.keyFor(selector) != null) ;
    while (writeSelectableChannel.keyFor(selector) != null) ;

    writeSelectableChannel.close();
    readSelectableChannel.close();
  }
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
    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);
  }
  public void stop() {
    try {
      lock.lock();

      if (networkJob != null && !networkJob.isCancelled()) {
        networkJob.cancel(true);
        networkJob = null;
      }

      try {
        if (selector != null) {

          selector.wakeup();

          boolean isContinue = true;
          while (isContinue) {
            try {
              for (SelectionKey selectionKey : selector.keys()) {
                selectionKey.channel().close();
                selectionKey.cancel();
              }
              isContinue = false; // continue till all keys are cancelled
            } catch (ConcurrentModificationException e) {
              logger.warn(
                  "An exception occurred while closing a selector key : '{}'", e.getMessage());
            }
          }

          selector.close();
        }
      } catch (IOException e) {
        logger.warn("An exception occurred while closing the selector : '{}'", e.getMessage());
      }

      if (broadcastKey != null) {
        try {
          broadcastKey.channel().close();
        } catch (IOException e) {
          logger.warn(
              "An exception occurred while closing the broadcast channel : '{}'", e.getMessage());
        }
      }

      if (unicastKey != null) {
        try {
          unicastKey.channel().close();
        } catch (IOException e) {
          logger.warn(
              "An exception occurred while closing the unicast channel : '{}'", e.getMessage());
        }
      }

      ipAddress = null;
    } finally {
      lock.unlock();
    }
  }
  @Override
  protected void processKey(SelectionKey key) throws IOException {
    if (key.isAcceptable()) {
      if (key.channel() == commandServerChannel) {
        acceptCommand(key);
      } else {
        if (commandChannel == null) {
          throw new IOException("Unexpected");
        }

        accept(key);
      }
    } else {
      if (commandChannel == null) {
        throw new IOException("Unexpected");
      }

      if (key.isReadable() && pendingChannels.containsKey(key.channel())) {
        ByteChannel channel = (ByteChannel) key.channel();

        try {
          ByteBuffer readBuffer = pendingChannels.get(channel);
          int read = channel.read(readBuffer);
          if (read == -1) {
            throw new IOException("Pending channel closed");
          }

          if (readBuffer.position() >= 5) {
            readBuffer.flip();
            try {
              byte cmd = readBuffer.get();
              if (cmd == CMD_OPEN_CHANNEL_ACK) {
                int tunnelId = readBuffer.getInt();

                try {
                  registerLeftChannel(tunnelId, channel);
                  pendingChannels.remove(channel);
                } catch (IOException e) {
                  logger.log(Level.INFO, "Spooling error: " + e.getMessage(), e);
                  closeTunnel(tunnelId);
                }
              } else {
                throw new IOException("Unknown command");
              }
            } finally {
              readBuffer.compact();
            }
          }
        } catch (IOException e) {
          logger.log(Level.SEVERE, "PROTOCOL ERROR: " + e.getMessage(), e);
          close(channel);
        }
      } else {
        super.processKey(key);
      }
    }
  }
Example #14
0
  /** Handle a read event from a socket specified by the key. */
  private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    SocketAddress remoteAdr = socketChannel.socket().getRemoteSocketAddress();

    // 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) {
      // The remote forcibly closed the connection, cancel
      // the selection key and close the channel.
      key.cancel();
      socketChannel.close();
      clients.remove(remoteAdr);
      pendingWriteData.remove(socketChannel);
      logger.fine(
          "Connection forcibly closed("
              + remoteAdr
              + ")! Remaining connections: "
              + clients.size());
      throw new IOException("Remote forcibly closed the connection");
    }

    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();
      clients.remove(remoteAdr);
      pendingWriteData.remove(socketChannel);
      logger.fine("Connection Closed(" + remoteAdr + ")! Remaining connections: " + clients.size());
      throw new IOException("Remote closed the connection");
    }

    // Make a correctly sized copy of the data before handing it to the client
    // byte[] rspByteData = new byte[numRead];
    // System.arraycopy(readBuffer.array(), 0, rspByteData, 0, numRead);

    try {
      Object rspData = Converter.toObject(readBuffer.array());

      // Hand the data off to our worker thread
      if (worker != null) {
        logger.finer("Handling incoming message...");
        worker.processData(this, socketChannel.getRemoteAddress(), rspData);
      } else {
        logger.fine("No worker set, message unhandled!");
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
Example #15
0
  private SelectionKey checkIfSpinnedKey(final SelectionKey key) {
    if (!key.isValid()
        && key.channel().isOpen()
        && spinnedSelectorsHistory.containsKey(key.selector())) {
      final SelectionKey newKey = key.channel().keyFor(selector);
      newKey.attach(key.attachment());
      return newKey;
    }

    return key;
  }
  private void dispatch() throws IOException {
    SelectionKey key = null;
    for (SocketChannelOPSChangeRequest request : opsChangeRequstMap.values()) {
      key = request.getChannel().keyFor(selector);
      if (key != null) {
        // 写优先
        if ((request.getOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) {
          key.interestOps(SelectionKey.OP_WRITE);
          request.clearOps(SelectionKey.OP_WRITE);
        } else if ((request.getOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
          key.interestOps(SelectionKey.OP_READ);
          request.clearOps(SelectionKey.OP_READ);
        }
      }
    }

    isWeakuped.set(false);
    if (selector.select(WaveriderConfig.WAVERIDER_DEFAULT_NETWORK_TIME_OUT) <= 0) {
      return;
    }

    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
    while (iterator.hasNext()) {
      key = (SelectionKey) iterator.next();
      iterator.remove();
      try {
        if (!key.isValid()) {
          continue;
        } else if (key.isAcceptable()) {
          onAccept(key);
        } else if (key.isReadable()) {
          // readerExecutor.execute(new NetworkTask(key, NETWORK_OPERATION_READ));
          onRead(key);
        } else if (key.isWritable()) {
          // writerExecutor.execute(new NetworkTask(key, NETWORK_OPERATION_WRITE));
          onWrite(key);
        }
      } catch (IOException e) {
        // 客户端连接出问题
        Session session = (Session) key.attachment();
        if (session != null) {
          session.onException();
          // 释放Session
          sessionManager.freeSession(session);
        }
        opsChangeRequstMap.remove((SocketChannel) key.channel());
        key.cancel();
        key.channel().close();
        e.printStackTrace();
        logger.error("OOPS:Exception:", e);
      }
    }
  }
 public void serve(int port) throws IOException {
   ServerSocketChannel serverChannel = ServerSocketChannel.open();
   serverChannel.configureBlocking(false);
   ServerSocket ss = serverChannel.socket();
   InetSocketAddress address = new InetSocketAddress(port);
   ss.bind(address); // 2
   Selector selector = Selector.open(); // 2
   serverChannel.register(selector, SelectionKey.OP_ACCEPT); // 3
   final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());
   for (; ; ) {
     try {
       selector.select(); // 4
     } catch (IOException ex) {
       ex.printStackTrace();
       // handle exception
       break;
     }
     Set<SelectionKey> readyKeys = selector.selectedKeys(); // 5
     Iterator<SelectionKey> iterator = readyKeys.iterator();
     while (iterator.hasNext()) {
       SelectionKey key = iterator.next();
       iterator.remove();
       try {
         if (key.isAcceptable()) { // 6
           ServerSocketChannel server = (ServerSocketChannel) key.channel();
           SocketChannel client = server.accept();
           client.configureBlocking(false);
           client.register(
               selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, msg.duplicate()); // 7
           System.out.println("Accepted connection from " + client);
         }
         if (key.isWritable()) { // 8
           SocketChannel client = (SocketChannel) key.channel();
           ByteBuffer buffer = (ByteBuffer) key.attachment();
           while (buffer.hasRemaining()) {
             if (client.write(buffer) == 0) { // 9
               break;
             }
           }
           client.close(); // 10
         }
       } catch (IOException ex) {
         key.cancel();
         try {
           key.channel().close();
         } catch (IOException cex) {
           // ignore on close
         }
       }
     }
   }
 }
Example #18
0
  private void read(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();

    DataServerMessage tMessage;
    if (mReceivingData.containsKey(socketChannel)) {
      tMessage = mReceivingData.get(socketChannel);
    } else {
      tMessage = DataServerMessage.createBlockRequestMessage();
      mReceivingData.put(socketChannel, tMessage);
    }

    // Attempt to read off the channel
    int numRead;
    try {
      numRead = tMessage.recv(socketChannel);
    } catch (IOException e) {
      // The remote forcibly closed the connection, cancel the selection key and close the channel.
      key.cancel();
      socketChannel.close();
      mReceivingData.remove(socketChannel);
      mSendingData.remove(socketChannel);
      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();
      mReceivingData.remove(socketChannel);
      mSendingData.remove(socketChannel);
      return;
    }

    if (tMessage.isMessageReady()) {
      if (tMessage.getBlockId() <= 0) {
        LOG.error("Invalid block id " + tMessage.getBlockId());
        return;
      }

      key.interestOps(SelectionKey.OP_WRITE);
      LOG.info("Get request for " + tMessage.getBlockId());
      int lockId = mBlocksLocker.lock(tMessage.getBlockId());
      DataServerMessage tResponseMessage =
          DataServerMessage.createBlockResponseMessage(
              true, tMessage.getBlockId(), tMessage.getOffset(), tMessage.getLength());
      tResponseMessage.setLockId(lockId);
      mSendingData.put(socketChannel, tResponseMessage);
    }
  }
Example #19
0
  /** {@inheritDoc} */
  public SelectableChannel acceptWithoutRegistration(SelectionKey key) throws IOException {
    boolean isAccepted;
    int retryNum = 0;
    do {
      try {
        isAccepted = true;
        return ((ServerSocketChannel) key.channel()).accept();
      } catch (IOException ex) {
        if (!key.isValid()) throw ex;

        isAccepted = false;
        try {
          // Let's try to recover here from too many open file
          Thread.sleep(1000);
        } catch (InterruptedException ex1) {
          throw new IOException(ex1.getMessage());
        }
        logger.log(
            Level.WARNING,
            LogMessages.WARNING_GRIZZLY_TCPSELECTOR_HANDLER_ACCEPTCHANNEL_EXCEPTION(),
            ex);
      }
    } while (!isAccepted && retryNum++ < maxAcceptRetries);

    throw new IOException("Accept retries exceeded");
  }
Example #20
0
 public void run() {
   try {
     while (!flag) {
       System.out.println("waiting connected.......");
       selector.select();
       Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
       while (keys.hasNext()) {
         SelectionKey key = keys.next();
         keys.remove();
         if (key.isAcceptable()) {
           ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
           SocketChannel sc = ssc.accept();
           sc.configureBlocking(false);
           SelectionKey clientKey = sc.register(selector, SelectionKey.OP_READ);
           System.out.println(sc.socket().getInetAddress().getHostAddress() + " 已连接");
         }
         if (key.isReadable()) {
           read(key);
         }
       }
     }
   } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   }
 }
Example #21
0
  /**
   * Called when a new connection is pending on the underlying {@link ServerSocketChannel}.
   *
   * @param key The {@link SelectionKey} for the socket on which a connection is pending.
   * @throws IOException if an error occurs while accepting the new connection.
   */
  protected void accept(SelectionKey key) throws IOException {
    // Pull out the socket channel that has a connection pending
    ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();

    // Accept the connection
    SocketChannel socketChannel = serverSocketChannel.accept();
    Socket socket = socketChannel.socket();

    // Check if our AcceptPolicy will allow this new connection
    if (this.acceptPolicy != null
        && !this.acceptPolicy.shouldRetain(socketChannel, this.getSocketSelector().keys().size())) {
      if (log.logTrace()) {
        log.trace("Closing accepted connection (accept policy enforced)");
      }
      socketChannel.close();
      return;
    }

    this.registerChannel(socketChannel);

    // Register the new socket. This will promote it to an SSLSocket
    // if we're configured for HTTPS.
    this.registerSocket(socket, this.host, this.port, false);

    // Add the new SocketChannel to our Selector
    socketChannel.configureBlocking(false);
    SelectionKey acceptKey = socketChannel.register(this.getSocketSelector(), SelectionKey.OP_READ);

    this.resetClientTimer(socketChannel.socket());
  }
Example #22
0
  @Override
  public void run() {
    try {
      while (true) {
        this.selector.select(SELECT_MILLISECONDS);
        if (Thread.interrupted()) break;

        Iterator<SelectionKey> i = this.selector.selectedKeys().iterator();
        while (i.hasNext()) {
          SelectionKey key = i.next();
          SelectableChannel channel = key.channel();
          handleReadableChannel(key, channel);
          handleWritableChannel(key, channel);
          i.remove();
        }
      }
    } catch (ClosedByInterruptException e) {
      // User-requested interrupt, so clean up
    } catch (IOException e) {
      reportIOException(e);
    }

    for (Map.Entry<SelectableChannel, SelectableChannel> e : this.outputs.entrySet()) {
      closeChannelAndReportException(e.getKey());
      closeChannelAndReportException(e.getValue());
    }

    for (SelectableChannel c : this.outputBuffers.keySet()) closeChannelAndReportException(c);
  }
Example #23
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 {

        }
      }
    }
  }
  @Override
  public Void call() throws Exception {
    ServerSocketChannel clientConnection = (ServerSocketChannel) selectionKey.channel();
    SocketChannel channel = clientConnection.accept();

    if (channel != null) {
      channel.configureBlocking(false);

      LOGGER.info(
          String.format("%s accepted client connection from %s", name, channel.getRemoteAddress()));

      try {
        final HttpRequest.HttpRequestWrapper requestWrapper = requestParser.parse(read(channel));

        MethodHandler handler =
            RequestHandlerFactory.newInstance(requestWrapper.getRequestLine().getMethod());
        HttpResponse.HttpResponseWrapper responseWrapper = handler.handle(requestWrapper);
        write(channel, responseWrapper);
      } finally {
        channel.close();
      }

      LOGGER.info(String.format("%s is done.", name));
    }

    return null;
  }
  /**
   * Start the server running - accepting connections, receiving messages. If the server is already
   * running, it will not be started again. This method is designed to be called in its own thread
   * and will not return until the server is stopped.
   *
   * @throws RuntimeException if the server fails
   */
  public void run() {
    // ensure that the server is not started twice
    if (!state.compareAndSet(State.STOPPED, State.RUNNING)) {
      started(true);
      return;
    }

    Selector selector = null;
    ServerSocketChannel server = null;
    try {
      selector = Selector.open();
      server = ServerSocketChannel.open();
      server.socket().bind(new InetSocketAddress(port));
      server.configureBlocking(false);
      server.register(selector, SelectionKey.OP_ACCEPT);
      started(false);
      while (state.get() == State.RUNNING) {
        selector.select(100); // check every 100ms whether the server has been requested to stop
        for (Iterator<SelectionKey> it = selector.selectedKeys().iterator(); it.hasNext(); ) {
          SelectionKey key = it.next();
          try {
            // remove key from the ready list
            it.remove();
            if (key.isConnectable()) {
              ((SocketChannel) key.channel()).finishConnect();
            }
            if (key.isAcceptable()) {
              // accept connection
              SocketChannel client = server.accept();
              client.configureBlocking(false);
              client.socket().setTcpNoDelay(true);
              // channel is registered for further events such as read or write
              SelectionKey acceptKey = client.register(selector, SelectionKey.OP_READ);
              connection(acceptKey);
            }
            if (key.isReadable()) {
              for (ByteBuffer message : readIncomingMessage(key)) {
                messageReceived(message, key);
              }
            }
          } catch (IOException ioe) {
            resetKey(key);
            disconnected(key);
          }
        }
      }
    } catch (Throwable e) {
      throw new RuntimeException("Server failure: " + e.getMessage());
    } finally {
      try {
        selector.close();
        server.socket().close();
        server.close();
        state.set(State.STOPPED);
        stopped();
      } catch (Exception e) {
        // do nothing - server failed
      }
    }
  }
  /**
   * Read as many messages as available on the client connection.
   *
   * @param key the client connection to read.
   * @return the messages read.
   * @throws IOException if the client connection is closed.
   */
  private List<ByteBuffer> readIncomingMessage(SelectionKey key) throws IOException {
    ByteBuffer readBuffer = readBuffers.get(key);
    if (readBuffer == null) {
      readBuffer = ByteBuffer.allocate(defaultBufferSize);
      readBuffers.put(key, readBuffer);
    }
    // read data pending in the channel
    // 1), maybe only receive partial message even if message is not big
    // 2), maybe multiple messages exist, will try to read all them
    // 3), maybe a message is too big to be fully put into buffer, then this
    // read will repeat multiple times
    if (((ReadableByteChannel) key.channel()).read(readBuffer) == -1) {
      throw new IOException("Read on closed key");
    }

    readBuffer.flip();
    List<ByteBuffer> result = new ArrayList<ByteBuffer>();

    // process data received in the buffer
    // 1), if only partial message is received, keep using readBuffer for coming request
    // 2), if multiple messages in the buffer, so need while loop here
    // 3), if message is too big, re-allocate the readBuffer and keep reading
    // 4), one readMessage(..) handle at most one full message
    ByteBuffer msg = readMessage(key, readBuffer);
    while (msg != null) {
      result.add(msg);
      msg = readMessage(key, readBuffer);
    }

    return result;
  }
 /**
  * Send the given message to the given client. The message does not need to have the length of the
  * message prepended. It is not guaranteed the message will arrive, as it can't be determined if
  * writing on a closed connection (it could appear to work). This won't be known until later when
  * get a disconnected callback is made.
  *
  * @param channelKey the key of the client to which the message should be sent.
  * @param buffer the message to send.
  */
 public void write(SelectionKey channelKey, byte[] buffer) {
   short len = (short) buffer.length;
   byte[] lengthBytes = messageLength.lengthToBytes(len);
   // copying into byte buffer is actually faster than writing to channel twice over many (>10000)
   // runs
   ByteBuffer writeBuffer = ByteBuffer.allocate(len + lengthBytes.length);
   writeBuffer.put(lengthBytes);
   writeBuffer.put(buffer);
   writeBuffer.flip();
   if (buffer != null && state.get() == State.RUNNING) {
     int bytesWritten;
     try {
       // only 1 thread can write to a channel at a time
       SocketChannel channel = (SocketChannel) channelKey.channel();
       synchronized (channel) {
         bytesWritten = channel.write(writeBuffer);
       }
       if (bytesWritten == -1) {
         resetKey(channelKey);
         disconnected(channelKey);
       }
     } catch (Exception e) {
       resetKey(channelKey);
       disconnected(channelKey);
     }
   }
 }
    private void dispose(Selector localSelector, LinkedBlockingQueue localSelectorTasks) {
      Assert.eval(Thread.currentThread() == this);

      if (localSelector != null) {

        for (Object element : localSelector.keys()) {
          try {
            SelectionKey key = (SelectionKey) element;
            cleanupChannel(key.channel(), null);
          } catch (Exception e) {
            logger.warn("Exception trying to close channel", e);
          }
        }

        try {
          localSelector.close();
        } catch (Exception e) {
          if ((Os.isMac()) && (Os.isUnix()) && (e.getMessage().equals("Bad file descriptor"))) {
            // I can't find a specific bug about this, but I also can't seem to prevent the
            // exception on the Mac.
            // So just logging this as warning.
            logger.warn("Exception trying to close selector: " + e.getMessage());
          } else {
            logger.error("Exception trying to close selector", e);
          }
        }
      }
    }
 public void handleAccept(SelectionKey key) throws IOException {
   ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
   SocketChannel socketChannel = serverSocketChannel.accept();
   log.info("Server: accept client socket " + socketChannel);
   socketChannel.configureBlocking(false);
   socketChannel.register(key.selector(), SelectionKey.OP_READ);
 }
    private void doConnect(SelectionKey key) {
      SocketChannel sc = (SocketChannel) key.channel();
      TCConnectionImpl conn = (TCConnectionImpl) key.attachment();

      try {
        if (sc.finishConnect()) {
          sc.register(selector, SelectionKey.OP_READ, conn);
          conn.finishConnect();
        } else {
          String errMsg = "finishConnect() returned false, but no exception thrown";

          if (logger.isInfoEnabled()) {
            logger.info(errMsg);
          }

          conn.fireErrorEvent(new Exception(errMsg), null);
        }
      } catch (IOException ioe) {
        if (logger.isInfoEnabled()) {
          logger.info("IOException attempting to finish socket connection", ioe);
        }

        conn.fireErrorEvent(ioe, null);
      }
    }