/** * Write the contents of the socketWriteBuffer to the socket. For blocking * writes either then entire contents of the buffer will be written or an * IOException will be thrown. Partial blocking writes will not occur. * * @param block Should the write be blocking or not? * * @throws IOException If an I/O error such as a timeout occurs during the * write */ protected void doWrite(boolean block) throws IOException { socketBufferHandler.configureWriteBufferForRead(); doWrite(block, socketBufferHandler.getWriteBuffer()); }
protected void writeNonBlockingDirect(ByteBuffer from) throws IOException { // The socket write buffer capacity is socket.appWriteBufSize // TODO This only matters when using TLS. For non-TLS connections it // should be possible to write the ByteBuffer in a single write int limit = socketBufferHandler.getWriteBuffer().capacity(); int fromLimit = from.limit(); while (from.remaining() >= limit) { int newLimit = from.position() + limit; from.limit(newLimit); doWrite(false, from); from.limit(fromLimit); if (from.position() != newLimit) { // Didn't write the whole amount of data in the last // non-blocking write. // Exit the loop. return; } } if (from.remaining() > 0) { socketBufferHandler.configureWriteBufferForWrite(); transfer(from, socketBufferHandler.getWriteBuffer()); } }
/** * Writes directly to the network, bypassing the socket write buffer. * * @param from The ByteBuffer containing the data to be written * * @throws IOException If an IO error occurs during the write */ protected void writeBlockingDirect(ByteBuffer from) throws IOException { // The socket write buffer capacity is socket.appWriteBufSize // TODO This only matters when using TLS. For non-TLS connections it // should be possible to write the ByteBuffer in a single write int limit = socketBufferHandler.getWriteBuffer().capacity(); int fromLimit = from.limit(); while (from.remaining() >= limit) { from.limit(from.position() + limit); doWrite(true, from); from.limit(fromLimit); } if (from.remaining() > 0) { socketBufferHandler.configureWriteBufferForWrite(); transfer(from, socketBufferHandler.getWriteBuffer()); } }
protected boolean flushNonBlocking() throws IOException { boolean dataLeft = !socketBufferHandler.isWriteBufferEmpty(); // Write to the socket, if there is anything to write if (dataLeft) { doWrite(false); dataLeft = !socketBufferHandler.isWriteBufferEmpty(); } if (!dataLeft && !nonBlockingWriteBuffer.isEmpty()) { dataLeft = nonBlockingWriteBuffer.write(this, false); if (!dataLeft && !socketBufferHandler.isWriteBufferEmpty()) { doWrite(false); dataLeft = !socketBufferHandler.isWriteBufferEmpty(); } } return dataLeft; }
/** * Writes the provided data to the socket write buffer. If the socket write * buffer fills during the write, the content of the socket write buffer is * written to the network using a blocking write. Once that blocking write * is complete, this method starts to fill the socket write buffer again. * Depending on the size of the data to write, there may be multiple writes * to the network. On completion of this method there will always be space * remaining in the socket write buffer. * * @param buf The byte array containing the data to be written * @param off The offset within the byte array of the data to be written * @param len The length of the data to be written * * @throws IOException If an IO error occurs during the write */ protected void writeBlocking(byte[] buf, int off, int len) throws IOException { socketBufferHandler.configureWriteBufferForWrite(); int thisTime = transfer(buf, off, len, socketBufferHandler.getWriteBuffer()); while (socketBufferHandler.getWriteBuffer().remaining() == 0) { len = len - thisTime; off = off + thisTime; doWrite(true); socketBufferHandler.configureWriteBufferForWrite(); thisTime = transfer(buf, off, len, socketBufferHandler.getWriteBuffer()); } }
doWrite(true); writeBlockingDirect(from);
/** * Separate method so it can be re-used by the socket write buffer to write * data to the network * * @param from The ByteBuffer containing the data to be written * * @throws IOException If an IO error occurs during the write */ protected void writeNonBlockingInternal(ByteBuffer from) throws IOException { if (socketBufferHandler.isWriteBufferEmpty()) { writeNonBlockingDirect(from); } else { socketBufferHandler.configureWriteBufferForWrite(); transfer(from, socketBufferHandler.getWriteBuffer()); if (!socketBufferHandler.isWriteBufferWritable()) { doWrite(false); if (socketBufferHandler.isWriteBufferWritable()) { writeNonBlockingDirect(from); } } } }
while (!socketBufferHandler.isWriteBufferWritable()) { off = off + thisTime; doWrite(false); if (len > 0 && socketBufferHandler.isWriteBufferWritable()) { socketBufferHandler.configureWriteBufferForWrite();