/** * 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; }
/** * 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); } }