Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I know you want non-blocking NIO, but if you want a performant NIO server I would start with this as a base line if for no other reason than simplicity. Often the simplest is also the fastest.</p> <pre><code>package example.nio; import java.io.Closeable; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class NioEchoServer implements Runnable, Closeable { private final ExecutorService service = Executors.newCachedThreadPool(); private final ServerSocketChannel ssc; private volatile boolean closed = false; public NioEchoServer(int port) throws IOException { ssc = ServerSocketChannel.open(); ssc.socket().setReuseAddress(true); ssc.bind(new InetSocketAddress(port)); service.submit(this); } @Override public void run() { try { while (!closed) { SocketChannel sc = ssc.accept(); service.submit(new EchoHandler(sc)); } } catch (IOException e) { if (!closed) e.printStackTrace(); } finally { closeQuietly(ssc); } } @Override public void close() throws IOException { closed = true; service.shutdownNow(); closeQuietly(ssc); } static void closeQuietly(Closeable closeable) { try { if (closeable != null) closeable.close(); } catch (IOException ignored) { } } public int getPort() { return ssc.socket().getLocalPort(); } static class EchoHandler implements Runnable { private final SocketChannel sc; public EchoHandler(SocketChannel sc) { this.sc = sc; } @Override public void run() { ByteBuffer bb = ByteBuffer.allocateDirect(64 * 1024); try { while (!Thread.interrupted() &amp;&amp; sc.read(bb) &gt; 0) { int len = bb.position(); bb.flip(); while (bb.remaining() &gt; 0) sc.write(bb); // write everything a second time. bb.position(0); bb.limit(len); while (bb.remaining() &gt; 0) sc.write(bb); bb.clear(); } } catch (IOException e) { e.printStackTrace(); } finally { System.out.println("Server disconnected"); closeQuietly(sc); } } } } </code></pre> <hr> <pre><code>package example.nio; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.concurrent.atomic.AtomicLong; public class NioEchoClient { public static void main(String... arg) throws IOException, InterruptedException { NioEchoServer nes = new NioEchoServer(0); // use a free port. final SocketChannel sc = SocketChannel.open(new InetSocketAddress("localhost", nes.getPort())); // send data for 2 seconds. long writeCount = 0; final AtomicLong readCount = new AtomicLong(); long start = System.currentTimeMillis(); long end = start + 2000; Thread reader = new Thread(new Runnable() { @Override public void run() { ByteBuffer bb = ByteBuffer.allocateDirect(64 * 1024); bb.clear(); int read; try { while ((read = sc.read(bb)) &gt; 0) { bb.clear(); readCount.addAndGet(read); } } catch (IOException ignored) { } } }); reader.start(); ByteBuffer bb = ByteBuffer.allocateDirect(64 * 1024); while (end &gt; System.currentTimeMillis()) { bb.clear(); int write = sc.write(bb); if (write &lt; 0) throw new AssertionError("Unexpected disconnection?"); writeCount += write; } sc.shutdownOutput(); reader.join(); long time = System.currentTimeMillis() - start; System.out.printf("Wrote: %,d bytes and read: %,d bytes in %,d ms%n", writeCount, readCount.get(), time); sc.close(); nes.close(); } } </code></pre> <p>prints</p> <pre><code>Wrote: 186,318,848 bytes and read: 186,318,848 bytes in 2,001 ms </code></pre> <p>when I write twice as much as I read I get</p> <pre><code>Wrote: 118,161,408 bytes and read: 236,322,816 bytes in 2,002 ms </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload