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) {
         }
       }
     }
   }
 }
示例#2
0
 public int ready() throws IOException {
   if (descriptor.getChannel() instanceof SelectableChannel) {
     int ready_stat = 0;
     java.nio.channels.Selector sel =
         SelectorFactory.openWithRetryFrom(
             null, ((SelectableChannel) descriptor.getChannel()).provider());
     SelectableChannel selchan = (SelectableChannel) descriptor.getChannel();
     synchronized (selchan.blockingLock()) {
       boolean is_block = selchan.isBlocking();
       try {
         selchan.configureBlocking(false);
         selchan.register(sel, java.nio.channels.SelectionKey.OP_READ);
         ready_stat = sel.selectNow();
         sel.close();
       } catch (Throwable ex) {
       } finally {
         if (sel != null) {
           try {
             sel.close();
           } catch (Exception e) {
           }
         }
         selchan.configureBlocking(is_block);
       }
     }
     return ready_stat;
   } else {
     return newInputStream().available();
   }
 }
 private void driveClientIO() throws IOException, GearmanException {
   for (GearmanJobServerSession sess : sessionsMap.values()) {
     int interestOps = SelectionKey.OP_READ;
     if (sess.sessionHasDataToWrite()) {
       interestOps |= SelectionKey.OP_WRITE;
     }
     try {
       sess.getSelectionKey().interestOps(interestOps);
     } catch (IllegalStateException ise) {
       LOG.warn("Unable to drive IO for session " + sess + "," + " skipping.", ise);
       continue;
     }
   }
   ioAvailable.selectNow();
   Set<SelectionKey> keys = ioAvailable.selectedKeys();
   LOG.trace(
       "Driving IO for client "
           + this
           + ". "
           + keys.size()
           + " session(s) currently available for IO");
   Iterator<SelectionKey> iter = keys.iterator();
   while (iter.hasNext()) {
     SelectionKey key = iter.next();
     GearmanJobServerSession s = sessionsMap.get(key);
     s.driveSessionIO();
   }
 }
示例#4
0
  @Override
  public void run() {
    try {
      selector = Selector.open();

      while (true) {
        processSelectionQueue();

        int nKeys = selector.select(selectWaitTime); // blocking
        if (nKeys == 0) {
          continue;
        } else {
          logger.trace(String.format("Selector %d, keys num: %d", selectorNum, nKeys));
        }

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

        while (iter.hasNext()) {
          SelectionKey key = iter.next();
          iter.remove();

          logger.trace("Key operations: " + key.readyOps());

          if (key.isWritable()) {
            doWrite(key);
          }
        }
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
    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);
          }
        }
      }
    }
示例#6
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();
   }
 }
  @Test
  public void testReceiveIntoExistingBuffer() throws Exception {
    Selector selector = mock(Selector.class);
    when(selector.select(SteamSocket.timeout)).thenReturn(1);
    mockStatic(Selector.class);
    when(Selector.open()).thenReturn(selector);
    when(this.channel.register(selector, SelectionKey.OP_READ)).thenReturn(null);

    this.socket.buffer = ByteBuffer.allocate(10);

    final SteamSocket socket = this.socket;
    when(this.channel.read(any(ByteBuffer.class)))
        .thenAnswer(
            new Answer<Integer>() {
              public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
                socket.buffer.put("test".getBytes());
                return 4;
              }
            });

    assertEquals(4, this.socket.receivePacket(4));

    ByteBuffer buffer = this.socket.buffer;
    assertEquals(0, buffer.position());
    assertEquals(4, buffer.capacity());
    assertEquals("test", new String(buffer.array()));
  }
 public void run() {
   try {
     while (running) {
       int k;
       try {
         k = selector.select();
       } catch (IOException e) {
         manager.getLogger().info("Exception thrown by accept thread selector " + e);
         break;
       }
       if (k <= 0) {
         continue;
       }
       Set<SelectionKey> keys = selector.selectedKeys();
       Iterator<SelectionKey> i = keys.iterator();
       while (i.hasNext()) {
         SelectionKey key = i.next();
         ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
         SocketChannel channel;
         try {
           channel = serverChannel.accept();
         } catch (IOException e) {
           manager.getLogger().info("Exception thrown by server socket when accepting " + e);
           continue;
         }
         manager.addChannel(channel);
       }
     }
   } finally {
     cleanup();
   }
 }
示例#9
0
  private void do_selection() throws IOException {
    // wait for events
    // timeout 1000ms -> check for pendingChanges at least every second
    if (selector.select(1000) == 0) return;

    // wakeup to work on selected keys
    Iterator keys = selector.selectedKeys().iterator();
    while (keys.hasNext()) {
      SelectionKey key = (SelectionKey) keys.next();
      keys.remove();

      if (!key.isValid()) {
        continue;
      }

      if (key.isAcceptable()) {
        accept(key);
      } else if (key.isReadable()) {
        read(key);
      } else if (key.isWritable()) {
        write(key);
      } else if (key.isConnectable()) {
        connect(key);
      }
    }
  }
示例#10
0
  /**
   * 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());
      }
    }
  }
  @Override
  public void run() {
    while (true) {
      try {
        synchronized (_pendingRequest) {
          Iterator changes = _pendingRequest.iterator();
          while (changes.hasNext()) {
            ChangeRequest change = (ChangeRequest) changes.next();
            if (!processPendingRequest(change)) break;
            changes.remove();
          }
        }

        // wait events from selected channels
        _selector.select();

        Iterator selectedKeys = _selector.selectedKeys().iterator();
        while (selectedKeys.hasNext()) {
          SelectionKey key = (SelectionKey) selectedKeys.next();
          selectedKeys.remove();

          if (!key.isValid()) {
            continue;
          }

          processSelect(key);
        }
      } catch (Exception e) {
        logger.warning(Util.getErrorMessage(e));
      }
    }
  }
  /*
   * (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();
      }
  }
示例#13
0
文件: Overlord.java 项目: rf/bitster
  /** 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();
    }
  }
  public static void main(String[] args) throws IOException {
    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    serverSocketChannel.socket().bind(new InetSocketAddress(PORT));
    System.out.println("Server listening at port : " + PORT);
    serverSocketChannel.configureBlocking(false);
    Selector selector = Selector.open();
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

    while (true) {
      int n = selector.select();
      if (n == 0) {
        continue;
      }
      Iterator<SelectionKey> it = selector.selectedKeys().iterator();
      while (it.hasNext()) {
        SelectionKey key = it.next();
        if (key.isAcceptable()) {
          ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
          SocketChannel sc = ssc.accept();
          sc.configureBlocking(false);
          sc.register(selector, SelectionKey.OP_READ);
          System.out.println("accept client : " + sc);
          acceptClient(sc);
        }
        if (key.isReadable()) {
          readData(key);
        }
        it.remove();
      }
    }
  }
示例#15
0
  public static void main(String[] argv) throws Exception {
    Pipe[] pipes = new Pipe[PIPES_COUNT];
    Pipe pipe = Pipe.open();
    Pipe.SinkChannel sink = pipe.sink();
    Pipe.SourceChannel source = pipe.source();
    Selector sel = Selector.open();
    source.configureBlocking(false);
    source.register(sel, SelectionKey.OP_READ);

    for (int i = 0; i < PIPES_COUNT; i++) {
      pipes[i] = Pipe.open();
      Pipe.SourceChannel sc = pipes[i].source();
      sc.configureBlocking(false);
      sc.register(sel, SelectionKey.OP_READ);
      Pipe.SinkChannel sc2 = pipes[i].sink();
      sc2.configureBlocking(false);
      sc2.register(sel, SelectionKey.OP_WRITE);
    }

    for (int i = 0; i < LOOPS; i++) {
      sink.write(ByteBuffer.allocate(BUF_SIZE));
      int x = sel.selectNow();
      sel.selectedKeys().clear();
      source.read(ByteBuffer.allocate(BUF_SIZE));
    }

    for (int i = 0; i < PIPES_COUNT; i++) {
      pipes[i].sink().close();
      pipes[i].source().close();
    }
    pipe.sink().close();
    pipe.source().close();
    sel.close();
  }
示例#16
0
  @Override
  public void run() {
    Thread.currentThread().setName(threadName);
    while (started) {
      processRegisterTaskQueue();
      try {
        if (selector.select(1000) > 0) {
          Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
          while (iter.hasNext()) {
            SelectionKey key = iter.next();
            iter.remove();
            // 处理Key
            if (key.isReadable()) {
              processReadableKey(key);
            } else if (key.isWritable()) {
              processWritableKey(key);
            }
          }
          // TODO shutdown
        }
      } catch (IOException e) {
        logger.warn("Unexpected exception in the selector loop.", e);

        // Prevent possible consecutive immediate failures that lead to
        // excessive CPU consumption.
        try {
          Thread.sleep(1000);
        } catch (InterruptedException t) {
          // Ignore.
        }
      }
    }
  }
示例#17
0
 public ChannelListener(
     final int threadPoolSize,
     final StreamConsumerFactory consumerFactory,
     final BufferPool bufferPool,
     int timeout,
     TimeUnit unit,
     final boolean readSingleDatagram)
     throws IOException {
   this.executor =
       Executors.newScheduledThreadPool(
           threadPoolSize + 1); // need to allow for long running ChannelDispatcher thread
   this.serverSocketSelector = Selector.open();
   this.socketChannelSelector = Selector.open();
   this.bufferPool = bufferPool;
   this.initialBufferPoolSize = bufferPool.size();
   channelDispatcher =
       new ChannelDispatcher(
           serverSocketSelector,
           socketChannelSelector,
           executor,
           consumerFactory,
           bufferPool,
           timeout,
           unit,
           readSingleDatagram);
   executor.schedule(channelDispatcher, 50, TimeUnit.MILLISECONDS);
 }
示例#18
0
  @Override
  public void run() {
    try {
      System.out.println("[Server Opened]");
      selector = Selector.open();
      ssc.register(selector, SelectionKey.OP_ACCEPT);
      while (true) {
        int canalsPreparats = selector.select();
        if (canalsPreparats == 0) {
          continue;
        }
        Set<SelectionKey> clausSeleccionades = selector.selectedKeys();
        Iterator<SelectionKey> iterador = clausSeleccionades.iterator();
        while (iterador.hasNext()) {
          SelectionKey clau = iterador.next();

          // CONCURRENCIA claus
          // Les claus son un recurs compartit, ja que quan finalitza
          // el joc, el métode update() les cancela. Per aquest motiu
          // quan en fem us, synchronitzem el objecte, i comprovem
          // que siguin vàlides
          synchronized (this) {
            if (clau.isValid() && clau.isAcceptable()) {
              ferAccept(clau);
            } else if (clau.isValid() && clau.isReadable()) {
              rebre(clau);
            }
          }
          iterador.remove();
        }
      }
    } catch (IOException ex) {
    }
  }
示例#19
0
 boolean initiateConnection(Connection conn_, Peer peer) {
   TCPConnection conn = (TCPConnection) conn_;
   try {
     SocketChannel channel = SocketChannel.open();
     InetSocketAddress localAddress = new InetSocketAddress(conn.host_id, 0);
     channel.socket().bind(localAddress);
     channel.configureBlocking(false);
     try {
       InetSocketAddress remoteAddress = new InetSocketAddress(peer.host(), peer.port());
       if (channel.connect(remoteAddress)) {
         // This only happens on Solaris when connecting locally
         logger.log(Level.FINEST, "Connected!");
         conn.state = Connection.State.connected_out;
         conn.channel = channel;
         selector.wakeup();
         channel.register(selector, SelectionKey.OP_READ, conn);
         initiateCER(conn);
         return true;
       }
     } catch (java.nio.channels.UnresolvedAddressException ex) {
       channel.close();
       return false;
     }
     conn.state = Connection.State.connecting;
     conn.channel = channel;
     selector.wakeup();
     channel.register(selector, SelectionKey.OP_CONNECT, conn);
   } catch (java.io.IOException ex) {
     logger.log(
         Level.WARNING,
         "java.io.IOException caught while initiating connection to '" + peer.host() + "'.",
         ex);
   }
   return true;
 }
示例#20
0
  private boolean scheduleWriteIfNecessary(final SctpChannelImpl channel) {
    final Thread currentThread = Thread.currentThread();
    final Thread workerThread = thread;
    if (currentThread != workerThread) {
      if (channel.writeTaskInTaskQueue.compareAndSet(false, true)) {
        boolean offered = writeTaskQueue.offer(channel.writeTask);
        assert offered;
      }

      if (!(channel instanceof SctpAcceptedChannel)
          || ((SctpAcceptedChannel) channel).bossThread != currentThread) {
        final Selector workerSelector = selector;
        if (workerSelector != null) {
          if (wakenUp.compareAndSet(false, true)) {
            workerSelector.wakeup();
          }
        }
      } else {
        // A write request can be made from an acceptor thread (boss)
        // when a user attempted to write something in:
        //
        //   * channelOpen()
        //   * channelBound()
        //   * channelConnected().
        //
        // In this case, there's no need to wake up the selector because
        // the channel is not even registered yet at this moment.
      }

      return true;
    }

    return false;
  }
示例#21
0
  private void loop() {
    while (true) {
      try {
        selector.select();
        Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();
        while (selectedKeys.hasNext()) {
          SelectionKey key = selectedKeys.next();
          selectedKeys.remove();

          if (!key.isValid()) {
            continue;
          }

          // Check what event is available and deal with it
          if (key.isAcceptable()) {
            accept(key);
          } else if (key.isReadable()) {
            read(key);
          } else if (key.isWritable()) {
            write(key);
          }
        }

      } catch (Exception e) {
        e.printStackTrace();
        System.exit(1);
      }
    }
  }
示例#22
0
  @Override
  public void release() {
    try {
      mcastObject(null, slaves.length);
      flushBuffers(0);
    } catch (Exception e) {
      log.warn("Failed to send termination to slaves.", e);
    }
    try {
      discoverySelector.close();
    } catch (Throwable e) {
      log.warn("Error closing discovery selector", e);
    }
    try {
      communicationSelector.close();
    } catch (Throwable e) {
      log.warn("Error closing comunication selector", e);
    }
    for (SocketChannel sc : slaves) {
      try {
        sc.socket().close();
      } catch (Throwable e) {
        log.warn("Error closing channel", e);
      }
    }

    try {
      if (serverSocketChannel != null) serverSocketChannel.socket().close();
    } catch (Throwable e) {
      log.warn("Error closing server socket channel", e);
    }
  }
  // actual connection logic
  private void _connect() throws IOException {
    // Continuous loop that is only supposed to end when "close" is called.

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

    while (i.hasNext()) {
      SelectionKey key = i.next();
      i.remove();
      if (key.isConnectable()) {
        if (socketChannel.isConnectionPending()) {
          socketChannel.finishConnect();
        }
        socketChannel.register(selector, SelectionKey.OP_READ);
        _writeHandshake();
      }
      if (key.isReadable()) {
        try {
          _read();
        } catch (NoSuchAlgorithmException nsa) {
          this.onError(nsa);
        }
      }
    }
  }
示例#24
0
  public void run() {
    while (true) {
      try {
        synchronized (changeRequests) {
          Iterator changes = changeRequests.iterator();
          while (changes.hasNext()) {
            ChangeRequest change = (ChangeRequest) changes.next();
            switch (change.type) {
              case ChangeRequest.CHANGEOPS:
                SelectionKey key = change.socket.keyFor(selector);
                key.interestOps(change.ops);
            }
          }
          changeRequests.clear();
        }
        selector.select();

        Iterator selectedKeys = selector.selectedKeys().iterator();
        while (selectedKeys.hasNext()) {
          SelectionKey key = (SelectionKey) selectedKeys.next();
          selectedKeys.remove();

          if (!key.isValid()) continue;

          if (key.isAcceptable()) accept(key);
          else if (key.isReadable()) read(key);
          else if (key.isWritable()) write(key);
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
示例#25
0
 @Override
 public void run() {
   final Selector selector = this.selector;
   for (; ; ) {
     ++reactCount;
     try {
       selector.select(1000L);
       register(selector);
       Set<SelectionKey> keys = selector.selectedKeys();
       try {
         for (SelectionKey key : keys) {
           Object att = key.attachment();
           System.out.println("attchment " + att);
           if (att != null && key.isValid()) {
             int readyOps = key.readyOps();
             if ((readyOps & SelectionKey.OP_READ) != 0) {
               read((NIOConnection) att);
             } else if ((readyOps & SelectionKey.OP_WRITE) != 0) {
               write((NIOConnection) att);
             } else {
               key.cancel();
             }
           } else {
             key.cancel();
           }
         }
       } finally {
         keys.clear();
       }
     } catch (Throwable e) {
       LOGGER.warn(name, e);
     }
   }
 }
示例#26
0
  private void close(SctpServerChannelImpl channel, ChannelFuture future) {
    boolean bound = channel.isBound();
    try {
      if (channel.serverChannel.isOpen()) {
        channel.serverChannel.close();
        Selector selector = channel.selector;
        if (selector != null) {
          selector.wakeup();
        }
      }

      // Make sure the boss thread is not running so that that the future
      // is notified after a new connection cannot be accepted anymore.
      // See NETTY-256 for more information.
      channel.shutdownLock.lock();
      try {
        if (channel.setClosed()) {
          future.setSuccess();
          if (bound) {
            fireChannelUnbound(channel);
          }
          fireChannelClosed(channel);
        } else {
          future.setSuccess();
        }
      } finally {
        channel.shutdownLock.unlock();
      }
    } catch (Throwable t) {
      future.setFailure(t);
      fireExceptionCaught(channel, t);
    }
  }
示例#27
0
  /**
   * 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
      }
    }
  }
  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();
  }
示例#29
0
  public boolean waitEvent(long timeout) {
    int rc = 0;

    try {
      if (timeout == 0) {
        // waitEvent(0) is called every read/send of SocketBase
        // instant readiness is not strictly required
        // On the other hand, we can save lots of system call and increase performance
        return rcursor < wcursor.get();

      } else if (timeout < 0) {
        rc = selector.select(0);
      } else {
        rc = selector.select(timeout);
      }
    } catch (IOException e) {
      throw new ZError.IOException(e);
    }

    if (rc == 0) {
      return false;
    }

    selector.selectedKeys().clear();

    return true;
  }
示例#30
0
  @Override
  public void run() {
    while (!Thread.interrupted()) {
      try {
        selector.select();
      } catch (IOException e) {
        continue;
      }

      processRegisterChannels();

      Set<SelectionKey> keys = selector.selectedKeys();
      for (SelectionKey key : keys) {
        try {
          handle(key);
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
        } catch (Throwable throwable) {
          Logger.error("ChannelKey handle fail.", throwable);

          try {
            TimeUnit.MILLISECONDS.sleep(100);
          } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
          }
        }
      }
      keys.clear();
    }
  }