+ All Categories
Home > Software > Java NIO.2

Java NIO.2

Date post: 25-Jan-2017
Category:
Upload: instinctools
View: 411 times
Download: 0 times
Share this document with a friend
22
Java NIO.2
Transcript
Page 1: Java NIO.2

Java NIO.2

Page 2: Java NIO.2

Network socket

Network socket is an endpoint of a connection across a computer network.

Main types of Internet socket:

● Datagram sockets, which use User Datagram Protocol (UDP).

● Stream sockets, which use Transmission Control Protocol (TCP) or Stream Control Transmission Protocol (SCTP).

● Raw sockets, typically available in routers and other network equipment.

Page 3: Java NIO.2

Java IO vs NIO

IO NIO

Stream-oriented Buffer-oriented

Blocking I/O Non-blocking I/O

Selectors

Channels

Page 4: Java NIO.2

Java.IO - Stream-oriented

Data Source Program

Data Destination Program

001001001111001001001001011

001001001111001001001001011

Page 5: Java NIO.2

Java.IO - Blocking I/O

Socket Thread

read data, block until ready

read data, block until ready

write data, block until ready

write data, block until ready

Page 6: Java NIO.2

Java.IO — Work with data

// read from socketScanner sc = new Scanner(socket.getInputStream());String string = sc.nextLine();System.out.println("Received " + string);

// write to socketPrintWriter pw = new PrintWriter(socket.getOutputStream());pw.println("Hello");

Page 7: Java NIO.2

Java.NIO — Buffer-oriented & Non-blocking I/O

Channel Buffer Thread

read data into buffer

fill data into buffer

check data in buffer

goto top

Page 8: Java NIO.2

Java.NIO — Work with dataByteBuffer readBuffer = ByteBuffer.allocate(1024);// prepare to readreadBuffer.clear();SocketChannel channel = getChannel();channel.read(readBuffer);readBuffer.flip();// reading the buffer// ...............…

ByteBuffer writeBuffer = ByteBuffer.allocate(1024);// prepare to put datawriteBuffer.clear();// putting the data// ...............// prepare to writewriteBuffer.flip();channel.write(writeBuffer);

Page 9: Java NIO.2

Java.NIO — Selector & Channels

Channel is a lightweight entity effeciently transporting data between sockets as a tube.

Selector is a manager allowing a single thread to monitor multiple input channels.

Page 10: Java NIO.2

Java.IO - Classic IO server design

ServerSocket Thread

Connection Thread

Connection Thread

Connection Thread

Connection Thread

Page 11: Java NIO.2

Java.NIO — NIO server design

Thread

Selector

Channel Channel Channel Channel

Page 12: Java NIO.2

Java.NIO — NIO server designServerSocketChannel channel = ServerSocketChannel.open();channel.bind(new InetSocketAddress("localhost", 2222));channel.configureBlocking(false);

Selector selector = Selector.open();SelectionKey key = channel.register(selector, SelectionKey.OP_ACCEPT);

while (true) { if (selector.select() == 0) { Thread.sleep(1); continue; } Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey selectionKey = keyIterator.next(); if (selectionKey.isAcceptable()) { // a connection was accepted by a ServerSocketChannel. } else if (selectionKey.isConnectable()) { // a connection was established with a remote. } else if (selectionKey.isReadable()) { // a channel is ready for reading } else if (selectionKey.isWritable()) { // a channel is ready for writing } keyIterator.remove(); }}

Page 13: Java NIO.2

Java NIO.1 vs NIO.2

NIO.1 NIO.2Selector AsynchronousChannelGroup

ServerSocketChannel AsynchronousServerSocketChannel

SocketChannel AsynchronousSocketChannel

SelectionKey CompletionHandler

Page 14: Java NIO.2

Java.NIO.2 — Reading

ByteBuffer readBuffer = ByteBuffer.allocate(1024);// prepare to readreadBuffer.clear();

AsynchronousSocketChannel channel = getChannel2();channel.read(readBuffer, null, new CompletionHandler<Integer, Object>() { @Override public void completed(Integer result, Object attachment) { // buffer is ready for read } @Override public void failed(Throwable exc, Object attachment) { exc.printStackTrace(); }});

Page 15: Java NIO.2

Java.NIO.2 — WritingByteBuffer writeBuffer = ByteBuffer.allocate(1024);// prepare to put datawriteBuffer.clear();// putting data// ...............// prepare to writewriteBuffer.flip();

AsynchronousSocketChannel channel = getChannel2();channel.write(writeBuffer, null, new CompletionHandler<Integer, Object>() { @Override public void completed(Integer result, Object attachment) { // writing has been completed } @Override public void failed(Throwable exc, Object attachment) { exc.printStackTrace(); }});

Page 16: Java NIO.2

Java.NIO — NIO.1 server designServerSocketChannel channel = ServerSocketChannel.open();channel.bind(new InetSocketAddress("localhost", 2222));channel.configureBlocking(false);

Selector selector = Selector.open();SelectionKey key = channel.register(selector, SelectionKey.OP_ACCEPT);

while (true) { if (selector.select() == 0) { Thread.sleep(1); continue; } Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey selectionKey = keyIterator.next(); if (selectionKey.isAcceptable()) { // a connection was accepted by a ServerSocketChannel. } else if (selectionKey.isConnectable()) { // a connection was established with a remote. } else if (selectionKey.isReadable()) { // a channel is ready for reading } else if (selectionKey.isWritable()) { // a channel is ready for writing } keyIterator.remove(); }}

Page 17: Java NIO.2

Java.NIO — NIO.2 server designAsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(newFixedThreadPool(10));

AsynchronousServerSocketChannel channel = open(group);channel.bind(new InetSocketAddress("localhost", 2222));channel.accept(null, toHandler((client, attach) -> { ByteBuffer readBuffer = ByteBuffer.allocate(1024); ByteBuffer writeBuffer = ByteBuffer.allocate(1024); client.read(readBuffer, null, toHandler((result, attachment) -> { // buffer is ready for read })); client.write(writeBuffer, null, toHandler((result, attachment) -> { // writing has been completed }));}));

Page 18: Java NIO.2

public class NetworkServer { AsynchronousServerSocketChannel channel; CompletionHandler<AsynchronousSocketChannel, Void> handler; public NetworkServer(SocketAddress address) throws IOException { AsynchronousChannelGroup group = withFixedThreadPool(10, Thread::new); handler = toHandler((channel, attach) -> processAccept(channel)); channel = AsynchronousServerSocketChannel.open(group); channel.bind(address); channel.accept(null, toHandler((clientChannel, attach) -> processAccept(clientChannel))); }

private void processAccept(AsynchronousSocketChannel clientChannel) { NetworkClient networkClient = new NetworkClient(clientChannel, message -> out.println("Server: received: " + message)); networkClient.write("Hello! I'm NIO.2 server!\n"); channel.accept(null, handler); }

public void stop() throws IOException { channel.close(); }}

Java NIO.2 — Basic implementation of server

Page 19: Java NIO.2

public class NetworkClient { AtomicBoolean isWriting = new AtomicBoolean(); Deque<String> toWrite = new ConcurrentLinkedDeque<>(); Consumer<String> readFunction; CompletionHandler<Integer, ByteBuffer> readHandler = toHandler((byteCount, buffer) -> finishRead(byteCount)); CompletionHandler<Integer, ByteBuffer> writeHandler = toHandler((byteCount, buffer) -> finishWrite()); ByteBuffer rb = allocateDirect(1024); ByteBuffer wb = allocateDirect(1024); AsynchronousSocketChannel channel; public NetworkClient(AsynchronousSocketChannel channel, Consumer<String> readFunction) { this.channel = channel; this.readFunction = readFunction; readNext(); } private void finishRead(Integer byteCount) { if(byteCount.equals(-1)) return; readFunction.accept(NUtils.read(rb)); readNext(); } private void finishWrite() { if (isWriting.compareAndSet(true, false)) writeNext(); } public void write(String message) { toWrite.add(message); if(isWriting.compareAndSet(false, true)) writeNext(); } private void writeNext() { if(toWrite.isEmpty()) return; NUtils.write(wb, toWrite); channel.write(wb, wb, writeHandler); } private void readNext() { channel.read(rb, rb, readHandler); }}

Java NIO.2 — Basic implementation of server

Page 20: Java NIO.2

new Thread(run(() -> { final NetworkServer server = new NetworkServer(new InetSocketAddress(3333)); ConcurrentUtils.wait(counter); server.stop();})).start();

ThreadUtils.sleep(1000);

for (int i = 0, length = CLIENT_COUNT; i < length; i++) { new Thread(run(() -> { Socket socket = new Socket(); socket.connect(new InetSocketAddress(3333)); writeLine(socket, "Hello! I'm client " + currentThread().getName()); System.out.println("Client: received: " + readLine(socket)); synchronized (counter) { if (counter.decrementAndGet() == 0) { ConcurrentUtils.notifyAll(counter); } else { ConcurrentUtils.wait(counter); } } socket.close(); })).start();}

Java NIO.2 — Test

Page 21: Java NIO.2

Java NIO.2 — Test

Server: received: Hello! I'm client Thread-16Server: received: Hello! I'm client Thread-19Server: received: Hello! I'm client Thread-11Server: received: Hello! I'm client Thread-20Server: received: Hello! I'm client Thread-15Server: received: Hello! I'm client Thread-18Server: received: Hello! I'm client Thread-12Server: received: Hello! I'm client Thread-14Server: received: Hello! I'm client Thread-13Server: received: Hello! I'm client Thread-17Client: received: Hello! I'm NIO.2 server!Client: received: Hello! I'm NIO.2 server!Client: received: Hello! I'm NIO.2 server!Client: received: Hello! I'm NIO.2 server!Client: received: Hello! I'm NIO.2 server!Client: received: Hello! I'm NIO.2 server!Client: received: Hello! I'm NIO.2 server!Client: received: Hello! I'm NIO.2 server!Client: received: Hello! I'm NIO.2 server!Client: received: Hello! I'm NIO.2 server!

Page 22: Java NIO.2

All thanks

Repository with my code examples:https://bitbucket.org/JavaSabr/publictest


Recommended