예제 #1
0
    /**
     * writes the contents of the buffer to the socket
     *
     * @param socketChannel the socket to publish the buffer to
     * @param approxTime an approximation of the current time in millis
     * @throws IOException
     */
    private int writeBufferToSocket(
        @NotNull final SocketChannel socketChannel, final long approxTime) throws IOException {

      if (in.position() == 0) return 0;

      // if we still have some unwritten writer from last time
      lastSentTime = approxTime;
      out.limit((int) in.position());

      final int len = socketChannel.write(out);

      if (LOG.isDebugEnabled()) LOG.debug("bytes-written=" + len);

      if (out.remaining() == 0) {
        out.clear();
        in.clear();
      } else {
        out.compact();
        in.position(out.position());
        in.limit(in.capacity());
        out.clear();
      }

      return len;
    }
    SelectableChannel doConnect() throws IOException, InterruptedException {

      final DatagramChannel server = DatagramChannel.open();
      server.configureBlocking(false);

      // Kick off connection establishment
      try {
        // Create a non-blocking socket channel
        server.socket().setBroadcast(true);
        server.connect(socketAddress);
      } catch (IOException e) {
        if (LOG.isDebugEnabled())
          LOG.debug("details=" + new Details(socketAddress, localIdentifier), e);
        connectLater();
        return null;
      }

      server
          .setOption(SO_REUSEADDR, true)
          .setOption(StandardSocketOptions.IP_MULTICAST_LOOP, false)
          .setOption(StandardSocketOptions.SO_BROADCAST, true)
          .setOption(SO_REUSEADDR, true);
      if (networkInterface != null)
        server.setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface);

      // the registration has be be run on the same thread as the selector
      addPendingRegistration(
          new Runnable() {
            @Override
            public void run() {
              try {
                server.register(selector, OP_WRITE);
                writeChannel = server;
                throttle(server);
              } catch (ClosedChannelException e) {
                LOG.error("", e);
              }
            }
          });

      return server;
    }
예제 #3
0
    /**
     * removes back in the OP_WRITE from the selector, otherwise it'll spin loop. The OP_WRITE will
     * get added back in as soon as we have data to write
     *
     * @param socketChannel the socketChannel we wish to stop writing to
     * @param attached data associated with the socketChannels key
     */
    public synchronized void disableWrite(
        @NotNull final SocketChannel socketChannel, @NotNull final Attached attached) {
      try {
        SelectionKey key = socketChannel.keyFor(selector);
        if (key != null) {
          if (attached.isHandShakingComplete() && selector.isOpen()) {
            if (LOG.isDebugEnabled())
              LOG.debug(
                  "Disabling OP_WRITE to remoteIdentifier="
                      + attached.remoteIdentifier
                      + ", localIdentifier="
                      + localIdentifier);
            key.interestOps(key.interestOps() & ~OP_WRITE);
          }
        }

      } catch (Exception e) {
        LOG.error("", e);
      }
    }