/**
   * Serves the incoming connections.
   *
   * @throws IOException
   * @throws DirectoryException
   */
  private void serveIncomingConnections() throws IOException, DirectoryException {
    int selectorState = selector.select();

    // We can't rely on return value of select to determine if any keys
    // are ready.
    // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4850373
    for (Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
        iterator.hasNext(); ) {
      SelectionKey key = iterator.next();
      iterator.remove();
      if (key.isAcceptable()) {
        // Accept the new client connection.
        ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
        SocketChannel clientChannel = serverChannel.accept();
        if (clientChannel != null) {
          acceptConnection(clientChannel);
        }
      }

      if (selectorState == 0 && enabled && !shutdownRequested && logger.isTraceEnabled()) {
        // Selected keys was non empty but select() returned 0.
        // Log warning and hope it blocks on the next select() call.
        logger.trace(
            "Selector.select() returned 0. "
                + "Selected Keys: %d, Interest Ops: %d, Ready Ops: %d ",
            selector.selectedKeys().size(), key.interestOps(), key.readyOps());
      }
    }
  }
Beispiel #2
0
 private void dispatch() throws IOException {
   sel.select();
   for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) {
     SelectionKey sk = (SelectionKey) i.next();
     i.remove();
     Handler h = (Handler) sk.attachment();
     h.handle(sk);
   }
 }
Beispiel #3
0
 protected void handleClient(SelectionKey key) throws IOException {
   SocketChannel sc = (SocketChannel) key.channel();
   ClientInfo ci = (ClientInfo) allClients.get(sc);
   if (ci == null) throw new IllegalStateException("Unknown client");
   if (key.isWritable()) send(sc, ci);
   if (key.isReadable())
     // 从一个客户端读进所有的可用数据
     recv(sc, ci);
 }
Beispiel #4
0
  static void test() throws Exception {
    ServerSocketChannel ssc = null;
    SocketChannel sc = null;
    SocketChannel peer = null;
    try {
      ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));

      // loopback connection
      InetAddress lh = InetAddress.getLocalHost();
      sc = SocketChannel.open(new InetSocketAddress(lh, ssc.socket().getLocalPort()));
      peer = ssc.accept();

      // peer sends message so that "sc" will be readable
      int n = peer.write(ByteBuffer.wrap("Hello".getBytes()));
      assert n > 0;

      sc.configureBlocking(false);

      Selector selector = Selector.open();
      SelectionKey key = sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);

      boolean done = false;
      int failCount = 0;
      while (!done) {
        int nSelected = selector.select();
        if (nSelected > 0) {
          if (nSelected > 1) throw new RuntimeException("More than one channel selected");
          Set<SelectionKey> keys = selector.selectedKeys();
          Iterator<SelectionKey> iterator = keys.iterator();
          while (iterator.hasNext()) {
            key = iterator.next();
            iterator.remove();
            if (key.isWritable()) {
              failCount++;
              if (failCount > 10) throw new RuntimeException("Test failed");
              Thread.sleep(250);
            }
            if (key.isReadable()) {
              done = true;
            }
          }
        }
      }
    } finally {
      if (peer != null) peer.close();
      if (sc != null) sc.close();
      if (ssc != null) ssc.close();
    }
  }
  void processIO() {
    Iterator<SelectionKey> it = mySelector.selectedKeys().iterator();
    while (it.hasNext()) {
      SelectionKey k = it.next();
      it.remove();

      if (k.isConnectable()) isConnectable(k);
      else if (k.isAcceptable()) isAcceptable(k);
      else {
        if (k.isWritable()) isWritable(k);

        if (k.isReadable()) isReadable(k);
      }
    }
  }
  void isReadable(SelectionKey k) {
    EventableChannel ec = (EventableChannel) k.attachment();
    long b = ec.getBinding();

    if (ec.isWatchOnly()) {
      if (ec.isNotifyReadable()) eventCallback(b, EM_CONNECTION_NOTIFY_READABLE, null);
    } else {
      myReadBuffer.clear();

      try {
        ec.readInboundData(myReadBuffer);
        myReadBuffer.flip();
        if (myReadBuffer.limit() > 0) {
          if (ProxyConnections != null) {
            EventableChannel target = ProxyConnections.get(b);
            if (target != null) {
              ByteBuffer myWriteBuffer = ByteBuffer.allocate(myReadBuffer.limit());
              myWriteBuffer.put(myReadBuffer);
              myWriteBuffer.flip();
              target.scheduleOutboundData(myWriteBuffer);
            } else {
              eventCallback(b, EM_CONNECTION_READ, myReadBuffer);
            }
          } else {
            eventCallback(b, EM_CONNECTION_READ, myReadBuffer);
          }
        }
      } catch (IOException e) {
        UnboundConnections.add(b);
      }
    }
  }
Beispiel #7
0
  public void run() {
    try {
      SocketChannel sc = SocketChannel.open();
      InetSocketAddress sinaAddr = new InetSocketAddress("sina.com", 80);
      sc.socket().connect(sinaAddr);

      // init a selector via helper class selector provider
      Selector aSel = SelectorProvider.provider().openSelector();

      Socket soc = new Socket("host", 80);
      soc.getChannel().register(aSel, SelectionKey.OP_ACCEPT);

      // init a channel for server socket. method 1
      ServerSocketChannel ssc = ServerSocketChannel.open();
      ssc.configureBlocking(true);

      // method 2, get server socket first, then init its channel
      ServerSocket ss = new ServerSocket();
      ServerSocketChannel ssc2 = ss.getChannel();

      // set socket channel as non blocking.
      ssc.configureBlocking(false);

      InetSocketAddress isa = new InetSocketAddress("localhost", 9999);
      ssc.socket().bind(isa);

      SelectionKey acceptKey = ssc.register(aSel, SelectionKey.OP_ACCEPT);
      int keysAdded = 0;
      while ((keysAdded = aSel.select()) > 0) {
        Set readyKeys = aSel.selectedKeys();
        Iterator i = readyKeys.iterator();
        while (i.hasNext()) {
          SelectionKey sk = (SelectionKey) i.next();
          i.remove();
          ServerSocketChannel n = (ServerSocketChannel) sk.channel();
          // now we got a new socket and its channel after accept in server
          Socket s = n.accept().socket();
          SocketChannel socketChannel = s.getChannel();
          socketChannel.register(aSel, SelectionKey.OP_READ);
        }
      }
    } catch (Exception e) {

    }
  }
  /**
   * Cleans up the contents of the selector, closing any server socket channels that might be
   * associated with it. Any connections that might have been established through those channels
   * should not be impacted.
   */
  private void cleanUpSelector() {
    try {
      for (SelectionKey key : selector.keys()) {
        try {
          key.cancel();
        } catch (Exception e) {
          logger.traceException(e);
        }

        try {
          key.channel().close();
        } catch (Exception e) {
          logger.traceException(e);
        }
      }
    } catch (Exception e) {
      logger.traceException(e);
    }
  }
  void isConnectable(SelectionKey k) {
    EventableSocketChannel ec = (EventableSocketChannel) k.attachment();
    long b = ec.getBinding();

    try {
      if (ec.finishConnecting()) eventCallback(b, EM_CONNECTION_COMPLETED, null);
      else UnboundConnections.add(b);
    } catch (IOException e) {
      UnboundConnections.add(b);
    }
  }
Beispiel #10
0
  /** Selects on sockets and informs their Communicator when there is something to do. */
  public void communicate(int timeout) {

    try {
      selector.select(timeout);
    } catch (IOException e) {
      // Not really sure why/when this happens yet
      return;
    }

    Iterator<SelectionKey> keys = selector.selectedKeys().iterator();

    while (keys.hasNext()) {
      SelectionKey key = keys.next();
      keys.remove();
      if (!key.isValid()) continue; // WHY
      Communicator communicator = (Communicator) key.attachment();

      if (key.isReadable()) communicator.onReadable();
      if (key.isWritable()) communicator.onWritable();
      if (key.isAcceptable()) communicator.onAcceptable();
    }

    // Go through the queue and handle each communicator
    while (!queue.isEmpty()) {
      Communicator c = queue.poll();
      c.onMemo();
    }
  }
  void isAcceptable(SelectionKey k) {
    ServerSocketChannel ss = (ServerSocketChannel) k.channel();
    SocketChannel sn;
    long b;

    for (int n = 0; n < 10; n++) {
      try {
        sn = ss.accept();
        if (sn == null) break;
      } catch (IOException e) {
        e.printStackTrace();
        k.cancel();

        ServerSocketChannel server = Acceptors.remove(k.attachment());
        if (server != null)
          try {
            server.close();
          } catch (IOException ex) {
          }
        ;
        break;
      }

      try {
        sn.configureBlocking(false);
      } catch (IOException e) {
        e.printStackTrace();
        continue;
      }

      b = createBinding();
      EventableSocketChannel ec = new EventableSocketChannel(sn, b, mySelector);
      Connections.put(b, ec);
      NewConnections.add(b);

      eventCallback(((Long) k.attachment()).longValue(), EM_CONNECTION_ACCEPTED, null, b);
    }
  }
  void isWritable(SelectionKey k) {
    EventableChannel ec = (EventableChannel) k.attachment();
    long b = ec.getBinding();

    if (ec.isWatchOnly()) {
      if (ec.isNotifyWritable()) eventCallback(b, EM_CONNECTION_NOTIFY_WRITABLE, null);
    } else {
      try {
        if (!ec.writeOutboundData()) UnboundConnections.add(b);
      } catch (IOException e) {
        UnboundConnections.add(b);
      }
    }
  }
  public void processSelectedKeys() throws IOException {
    // 处理连接就绪事件
    for (Iterator it = selector.selectedKeys().iterator(); it.hasNext(); ) {
      SelectionKey selectionKey = (SelectionKey) it.next();
      it.remove();

      Target target = (Target) selectionKey.attachment();
      SocketChannel socketChannel = (SocketChannel) selectionKey.channel();

      try {
        if (socketChannel.finishConnect()) {
          selectionKey.cancel();
          target.connectFinish = System.currentTimeMillis();
          socketChannel.close();
          addFinishedTarget(target);
        }
      } catch (IOException x) {
        socketChannel.close();
        target.failure = x;
        addFinishedTarget(target);
      }
    }
  }
Beispiel #14
0
    void processSelectedKeys() throws IOException {
      for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) {

        SelectionKey sk = (SelectionKey) i.next();
        i.remove();

        Target t = (Target) sk.attachment();
        SocketChannel sc = (SocketChannel) sk.channel();

        try {
          if (sc.finishConnect()) {
            sk.cancel();
            t.connectFinish = System.currentTimeMillis();
            sc.close();
            printer.add(t);
          }
        } catch (IOException x) {
          sc.close();
          t.failure = x;
          printer.add(t);
        }
      }
    }
Beispiel #15
0
  void isReadable(SelectionKey k) {
    EventableChannel ec = (EventableChannel) k.attachment();
    long b = ec.getBinding();

    if (ec.isWatchOnly()) {
      if (ec.isNotifyReadable()) eventCallback(b, EM_CONNECTION_NOTIFY_READABLE, null);
    } else {
      myReadBuffer.clear();

      try {
        ec.readInboundData(myReadBuffer);
        myReadBuffer.flip();
        if (myReadBuffer.limit() > 0) eventCallback(b, EM_CONNECTION_READ, myReadBuffer);
      } catch (IOException e) {
        UnboundConnections.add(b);
      }
    }
  }
 private void readMessage(SelectionKey sk, SocketChannel readChannel, TcpAddress incomingAddress)
     throws IOException {
   // note that socket has been used
   SocketEntry entry = (SocketEntry) sockets.get(incomingAddress);
   if (entry != null) {
     entry.used();
     ByteBuffer readBuffer = entry.getReadBuffer();
     if (readBuffer != null) {
       readChannel.read(readBuffer);
       if (readBuffer.hasRemaining()) {
         readChannel.register(selector, SelectionKey.OP_READ, entry);
       } else {
         dispatchMessage(incomingAddress, readBuffer, readBuffer.capacity());
       }
       return;
     }
   }
   ByteBuffer byteBuffer = ByteBuffer.wrap(buf);
   byteBuffer.limit(messageLengthDecoder.getMinHeaderLength());
   long bytesRead = readChannel.read(byteBuffer);
   if (logger.isDebugEnabled()) {
     logger.debug("Reading header " + bytesRead + " bytes from " + incomingAddress);
   }
   MessageLength messageLength = new MessageLength(0, Integer.MIN_VALUE);
   if (bytesRead == messageLengthDecoder.getMinHeaderLength()) {
     messageLength = messageLengthDecoder.getMessageLength(ByteBuffer.wrap(buf));
     if (logger.isDebugEnabled()) {
       logger.debug("Message length is " + messageLength);
     }
     if ((messageLength.getMessageLength() > getMaxInboundMessageSize())
         || (messageLength.getMessageLength() <= 0)) {
       logger.error(
           "Received message length "
               + messageLength
               + " is greater than inboundBufferSize "
               + getMaxInboundMessageSize());
       synchronized (entry) {
         entry.getSocket().close();
         logger.info("Socket to " + entry.getPeerAddress() + " closed due to an error");
       }
     } else {
       byteBuffer.limit(messageLength.getMessageLength());
       bytesRead += readChannel.read(byteBuffer);
       if (bytesRead == messageLength.getMessageLength()) {
         dispatchMessage(incomingAddress, byteBuffer, bytesRead);
       } else {
         byte[] message = new byte[byteBuffer.limit()];
         byteBuffer.flip();
         byteBuffer.get(message, 0, byteBuffer.limit() - byteBuffer.remaining());
         entry.setReadBuffer(ByteBuffer.wrap(message));
       }
       readChannel.register(selector, SelectionKey.OP_READ, entry);
     }
   } else if (bytesRead < 0) {
     logger.debug("Socket closed remotely");
     sk.cancel();
     readChannel.close();
     TransportStateEvent e =
         new TransportStateEvent(
             DefaultTcpTransportMapping.this,
             incomingAddress,
             TransportStateEvent.STATE_DISCONNECTED_REMOTELY,
             null);
     fireConnectionStateChanged(e);
   }
 }
    public void run() {
      // Here's where everything happens. The select method will
      // return when any operations registered above have occurred, the
      // thread has been interrupted, etc.
      try {
        while (!stop) {
          try {
            if (selector.select() > 0) {
              if (stop) {
                break;
              }
              // Someone is ready for I/O, get the ready keys
              Set readyKeys = selector.selectedKeys();
              Iterator it = readyKeys.iterator();

              // Walk through the ready keys collection and process date requests.
              while (it.hasNext()) {
                SelectionKey sk = (SelectionKey) it.next();
                it.remove();
                SocketChannel readChannel = null;
                TcpAddress incomingAddress = null;
                if (sk.isAcceptable()) {
                  // The key indexes into the selector so you
                  // can retrieve the socket that's ready for I/O
                  ServerSocketChannel nextReady = (ServerSocketChannel) sk.channel();
                  // Accept the date request and send back the date string
                  Socket s = nextReady.accept().socket();
                  readChannel = s.getChannel();
                  readChannel.configureBlocking(false);
                  readChannel.register(selector, SelectionKey.OP_READ);

                  incomingAddress = new TcpAddress(s.getInetAddress(), s.getPort());
                  SocketEntry entry = new SocketEntry(incomingAddress, s);
                  sockets.put(incomingAddress, entry);
                  timeoutSocket(entry);
                  TransportStateEvent e =
                      new TransportStateEvent(
                          DefaultTcpTransportMapping.this,
                          incomingAddress,
                          TransportStateEvent.STATE_CONNECTED,
                          null);
                  fireConnectionStateChanged(e);
                } else if (sk.isReadable()) {
                  readChannel = (SocketChannel) sk.channel();
                  incomingAddress =
                      new TcpAddress(
                          readChannel.socket().getInetAddress(), readChannel.socket().getPort());
                } else if (sk.isWritable()) {
                  try {
                    SocketEntry entry = (SocketEntry) sk.attachment();
                    SocketChannel sc = (SocketChannel) sk.channel();
                    if (entry != null) {
                      writeMessage(entry, sc);
                    }
                  } catch (IOException iox) {
                    if (logger.isDebugEnabled()) {
                      iox.printStackTrace();
                    }
                    logger.warn(iox);
                    TransportStateEvent e =
                        new TransportStateEvent(
                            DefaultTcpTransportMapping.this,
                            incomingAddress,
                            TransportStateEvent.STATE_DISCONNECTED_REMOTELY,
                            iox);
                    fireConnectionStateChanged(e);
                    sk.cancel();
                  }
                } else if (sk.isConnectable()) {
                  try {
                    SocketEntry entry = (SocketEntry) sk.attachment();
                    SocketChannel sc = (SocketChannel) sk.channel();
                    if ((!sc.isConnected()) && (sc.finishConnect())) {
                      sc.configureBlocking(false);
                      logger.debug("Connected to " + entry.getPeerAddress());
                      // make sure conncetion is closed if not used for timeout
                      // micro seconds
                      timeoutSocket(entry);
                      sc.register(selector, SelectionKey.OP_WRITE, entry);
                    }
                    TransportStateEvent e =
                        new TransportStateEvent(
                            DefaultTcpTransportMapping.this,
                            incomingAddress,
                            TransportStateEvent.STATE_CONNECTED,
                            null);
                    fireConnectionStateChanged(e);
                  } catch (IOException iox) {
                    if (logger.isDebugEnabled()) {
                      iox.printStackTrace();
                    }
                    logger.warn(iox);
                    sk.cancel();
                  }
                }

                if (readChannel != null) {
                  try {
                    readMessage(sk, readChannel, incomingAddress);
                  } catch (IOException iox) {
                    // IO exception -> channel closed remotely
                    if (logger.isDebugEnabled()) {
                      iox.printStackTrace();
                    }
                    logger.warn(iox);
                    sk.cancel();
                    readChannel.close();
                    TransportStateEvent e =
                        new TransportStateEvent(
                            DefaultTcpTransportMapping.this,
                            incomingAddress,
                            TransportStateEvent.STATE_DISCONNECTED_REMOTELY,
                            iox);
                    fireConnectionStateChanged(e);
                  }
                }
              }
            }
          } catch (NullPointerException npex) {
            // There seems to happen a NullPointerException within the select()
            npex.printStackTrace();
            logger.warn("NullPointerException within select()?");
          }
          processPending();
        }
        if (ssc != null) {
          ssc.close();
        }
      } catch (IOException iox) {
        logger.error(iox);
        lastError = iox;
      }
      if (!stop) {
        stop = true;
        synchronized (DefaultTcpTransportMapping.this) {
          server = null;
        }
      }
    }
  /** returns a list of rdpserversockets */
  Set<DatagramChannel> getActiveChannels() throws InterruptedException, java.io.IOException {
    lock.lock();
    try {
      while (channelMap.isEmpty()) {
        channelMapNotEmpty.await();
      }
    } finally {
      lock.unlock();
    }

    Set<SelectionKey> readyKeys = null;
    do {
      lock.lock();
      try {
        if (!newChannelSet.isEmpty()) {
          if (Log.loggingNet) Log.net("RDPServer.getActiveChannels: newChannelSet is not null");
          Iterator<DatagramChannel> iter = newChannelSet.iterator();
          while (iter.hasNext()) {
            DatagramChannel newDC = iter.next();
            iter.remove();
            newDC.register(selector, SelectionKey.OP_READ);
          }
        }
      } finally {
        lock.unlock();
      }
      int numReady = selector.select(); // this is a blocking call - thread safe
      selectCalls++;
      if (numReady == 0) {
        if (Log.loggingNet) Log.net("RDPServer.getActiveChannels: selector returned 0");
        continue;
      }
      readyKeys = selector.selectedKeys();
      if (Log.loggingNet)
        Log.net(
            "RDPServer.getActiveChannels: called select - # of ready keys = "
                + readyKeys.size()
                + " == "
                + numReady);
    } while (readyKeys == null || readyKeys.isEmpty());

    lock.lock();
    try {
      // get a datagramchannel that is ready
      Set<DatagramChannel> activeChannels = new HashSet<DatagramChannel>();

      Iterator<SelectionKey> iter = readyKeys.iterator();
      while (iter.hasNext()) {
        SelectionKey key = iter.next();
        if (Log.loggingNet)
          Log.net(
              "RDPServer.getActiveChannels: matched selectionkey: "
                  + key
                  + ", isAcceptable="
                  + key.isAcceptable()
                  + ", isReadable="
                  + key.isReadable()
                  + ", isValid="
                  + key.isValid()
                  + ", isWritable="
                  + key.isWritable());
        iter.remove(); // remove from the selected key list

        if (!key.isReadable() || !key.isValid()) {
          Log.error(
              "RDPServer.getActiveChannels: Throwing exception: RDPServer: not readable or invalid");
          throw new MVRuntimeException("RDPServer: not readable or invalid");
        }

        DatagramChannel dc = (DatagramChannel) key.channel();
        activeChannels.add(dc);
      }
      if (Log.loggingNet)
        Log.net(
            "RDPServer.getActiveChannels: returning " + activeChannels.size() + " active channels");
      return activeChannels;
    } finally {
      lock.unlock();
    }
  }
Beispiel #19
0
  public static void checkClients(List<SocketChannel> anonymousClients) {
    try {

      if (selector.selectNow() == 0) {
        return;
      }

      Set<SelectionKey> keys = selector.selectedKeys();
      for (SelectionKey key : keys) {

        if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
          SocketChannel clientSocket = serverSocket.accept();
          if (clientSocket == null) {
            System.err.println("Error: can not accept");
            continue;
          }
          anonymousClients.add(clientSocket);
          clientSocket.configureBlocking(false);
          clientSocket.register(selector, SelectionKey.OP_READ);
        } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
          SocketChannel clientSocket = (SocketChannel) key.channel();
          ByteBuffer bytes = ByteBuffer.allocate(4096);

          if (clientSocket.read(bytes) != -1) {
            byte[] message = bytes.array();
            switch (message[0]) {
              case 1:
                {
                  String nick = MessageUtils.parseMessage(message).first;
                  if (!checkMessage(nick, "", clientSocket)) {
                    continue;
                  }

                  if (clients.containsKey(nick) || nick.length() > 32) {
                    if (nick.length() > 32) {
                      sendMessage(
                          clientSocket, MessageUtils.error("<server>: your nick is too long"));
                    } else {
                      sendMessage(
                          clientSocket,
                          MessageUtils.error("<server>: another user is using this nick"));
                    }
                    sendMessage(clientSocket, MessageUtils.bye());
                    anonymousClients.remove(clientSocket);
                    Utils.tryClose(clientSocket);
                  } else {
                    System.out.println(nick + " enter this chatroom");
                    notifyAllClients(nick + " enter this chatroom");

                    sendMessage(
                        clientSocket,
                        MessageUtils.message("<server>", "Wellcome, your nick is " + nick));
                    anonymousClients.remove(clientSocket);
                    clients.put(nick, clientSocket);
                  }
                  break;
                }

              case 2:
                {
                  String nick = getNickFromSocket(clientSocket);
                  if (nick == null) {
                    Utils.printErrorAndExit("Error: it could not happen");
                  }

                  Utils.Pair<String, String> pair = MessageUtils.parseMessage(message);
                  if (!checkMessage(pair.first, pair.second, clientSocket)) {
                    continue;
                  }

                  if (!pair.first.equals(nick)) {
                    System.out.println("Cheater: " + nick);
                    sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat"));
                  }

                  for (Entry<String, SocketChannel> client : clients.entrySet()) {
                    if (!clientSocket.equals(client.getValue())) {
                      sendMessage(client.getValue(), MessageUtils.message(nick, pair.second));
                    }
                  }
                  break;
                }

              case 3:
                disconnectClient(clientSocket);
                break;

              case 127:
                {
                  String nick = getNickFromSocket(clientSocket);

                  Utils.Pair<String, String> pair = MessageUtils.parseMessage(message);
                  if (!checkMessage(pair.first, pair.second, clientSocket)) {
                    continue;
                  }

                  if (!pair.first.equals(nick)) {
                    System.out.println("Cheater: " + nick);
                    sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat"));
                  }
                  System.out.println(nick + ": " + pair.second);
                  break;
                }

              default:
                System.out.println("Bad message from " + getNickFromSocket(clientSocket));
                sendMessage(clientSocket, MessageUtils.message("<server>", "bad message"));
                break;
            }
          } else {
            disconnectClient(clientSocket);
          }
        }
      }
      keys.clear();
    } catch (Exception expt) {
      expt.printStackTrace();
      Utils.printErrorAndExit(expt.getMessage());
    }
  }
  private void go() throws IOException {
    // Create a new selector
    Selector selector = Selector.open();

    // Open a listener on each port, and register each one
    // with the selector
    for (int i = 0; i < ports.length; ++i) {
      ServerSocketChannel ssc = ServerSocketChannel.open();
      ssc.configureBlocking(false);
      ServerSocket ss = ssc.socket();
      InetSocketAddress address = new InetSocketAddress(ports[i]);
      ss.bind(address);

      SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT);

      System.out.println("Going to listen on " + ports[i]);
    }

    while (true) {
      int num = selector.select();

      Set selectedKeys = selector.selectedKeys();
      Iterator it = selectedKeys.iterator();

      while (it.hasNext()) {
        SelectionKey key = (SelectionKey) it.next();

        if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
          // Accept the new connection
          ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
          SocketChannel sc = ssc.accept();
          sc.configureBlocking(false);

          // Add the new connection to the selector
          SelectionKey newKey = sc.register(selector, SelectionKey.OP_READ);
          it.remove();

          System.out.println("Got connection from " + sc);
        } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
          // Read the data
          SocketChannel sc = (SocketChannel) key.channel();

          // Echo data
          int bytesEchoed = 0;
          while (true) {
            echoBuffer.clear();

            int r = sc.read(echoBuffer);

            if (r <= 0) {
              break;
            }

            echoBuffer.flip();

            sc.write(echoBuffer);
            bytesEchoed += r;
          }

          System.out.println("Echoed " + bytesEchoed + " from " + sc);

          it.remove();
        }
      }

      // System.out.println( "going to clear" );
      //      selectedKeys.clear();
      // System.out.println( "cleared" );
    }
  }
Beispiel #21
0
  public void init() throws IOException {
    this._logger = LoggerFactory.getLogger(AcquirePort.class);
    selector = Selector.open();
    // 通过open方法来打开一个未绑定的ServerSocketChannel实例
    ServerSocketChannel server = ServerSocketChannel.open();
    InetSocketAddress isa = new InetSocketAddress(_acquirePort);
    // 将该ServerSocketChannel绑定到指定IP地址
    server.socket().bind(isa);
    // 设置ServerSocket以非阻塞方式工作
    server.configureBlocking(false);
    // 将server注册到指定Selector对象
    server.register(selector, SelectionKey.OP_ACCEPT);
    // 定义准备执行读取数据的ByteBuffer
    ByteBuffer buff = ByteBuffer.allocate(1024);
    while (selector.select() > 0) {
      // 依次处理selector上的每个已选择的SelectionKey
      Set<SelectionKey> sks = selector.selectedKeys();
      Iterator keys = sks.iterator();
      while (keys.hasNext()) {
        SelectionKey sk = (SelectionKey) keys.next();
        // 从selector上的已选择Key集中删除正在处理的SelectionKey
        keys.remove();
        // 如果sk对应的通道包含客户端的连接请求
        if (sk.isAcceptable()) {
          // 调用accept方法接受连接,产生服务器端对应的SocketChannel
          SocketChannel sc = server.accept();
          // 设置采用非阻塞模式
          sc.configureBlocking(false);
          // 将该SocketChannel也注册到selector
          sc.register(selector, SelectionKey.OP_READ);
        }
        // 如果sk对应的通道有数据需要读取
        if (sk.isReadable()) {
          // 获取该SelectionKey对应的Channel,该Channel中有可读的数据
          SocketChannel sc = (SocketChannel) sk.channel();
          // 开始读取数据

          try {
            while (sc.read(buff) > 0) {
              buff.flip();
              this._logger.info("content" + buff);
              sc.write(buff);
              if (buff.hasRemaining()) {
                buff.compact();
              } else {
                buff.clear();
              }
            }
            // 打印从该sk对应的Channel里读取到的数据
            this._logger.info("accpect content" + buff);
          }
          // 如果捕捉到该sk对应的Channel出现了异常,即表明该Channel
          // 对应的Client出现了问题,所以从Selector中取消sk的注册
          catch (IOException ex) {
            // 从Selector中删除指定的SelectionKey
            sk.cancel();
            if (sk.channel() != null) {
              sk.channel().close();
            }
          }
        }
      }
    }
  }