Channel to NIO
Classification:
Client Channel
Connect the server
Delivery Buffer (Delivery Data)
Open Channel
Connect server (specify IP and port number) InetSocketAddress
write buffer to server
Release resources close
Code implementation:
public class test { public static void main(String[] args) throws IOException { //Open Channel SocketChannel open = SocketChannel.open(); //Specify IP and port number open.connect(new InetSocketAddress("127.0.0.1",1024)); //write ByteBuffer wrap = ByteBuffer.wrap("hello".getBytes()); open.write(wrap); //Release Resources open.close(); } }
Services Channel
The responsible connection of the server-side channel, not the transmission of data
1. Open a server-side channel
2. Bind the appropriate port number
3. Channel is blocked by default and needs to be set to non-blocked
4. Now there is no selector to join, the server needs to check whether there is data sent from time to time
5. If the client sends data, creating a client channel inside the server's channel is an extension of the client channel
6. Client passes buffer through channel to server
7. Server creates an empty buffer to load data and output
Client Channel connects to the server and transfers data
Buffer, data sent by client is in buffer
Client Channel created inside the Service End Channel, which is equivalent to an extension of the Client Channel used to transfer data
Code implementation:
public class NioServer { public static void main(String[] args) throws IOException { // 1. Open a server-side channel ServerSocketChannel open = ServerSocketChannel.open(); // 2. Bind the appropriate port number ServerSocketChannel bind = open.bind(new InetSocketAddress(1024)); // 3. Channel is blocked by default and needs to be set to non-blocked //If a true is passed, the channel is blocked. Default value //If a false is passed, the channel is non-blocking open.configureBlocking(false); // 4. Now there is no selector to join, the server needs to check whether there is data sent from time to time while (true) { // 5. If the client sends data, creating a client channel inside the server's channel is an extension of the client channel //Channel non-blocking is set up at this time, if there are clients to connect, then within the service-side channel, a client channel is created, which is equivalent to a client channel extension //If a method is called without a client to connect, it returns a null SocketChannel accept = open.accept(); if (open!=null){ // 6. Client passes buffer through channel to server // 7. Server creates an empty buffer to load data and output ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //Get the passed data and put them in the byteBuffer buffer //Return value: Positive number indicating the number of valid bytes for this supervision //0: No valid bytes read this time //-1 statement read to the end int read = accept.read(byteBuffer); System.out.println(new String(byteBuffer.array(),0,read)); accept.close(); } } } }
Exercise: Client sends data to server, server receives returns a data to client
Code:
Server:
public class NioServer { public static void main(String[] args) throws IOException { ServerSocketChannel open = ServerSocketChannel.open(); ServerSocketChannel bind = open.bind(new InetSocketAddress(1024)); open.configureBlocking(false); while (true){ SocketChannel accept = open.accept(); if (accept !=null){ System.out.println("A client is now connected"); //The second method is to set the extension channel as non-blocking accept.configureBlocking(false); //Get the data from the client and place it in the byteBuffer1 buffer ByteBuffer allocate = ByteBuffer.allocate(1024); //Cannot read only once by loop //accept.read(allocate); int len; //For buffers, get data flip method add data clear while ((len=accept.read(allocate))>0){ allocate.flip(); System.out.println(new String(allocate.array(),0,len)); allocate.clear(); } System.out.println("Receive data and write back a copy"); ByteBuffer wrap = ByteBuffer.wrap("This is the data returned".getBytes()); accept.write(wrap); accept.close(); } } } }
Client Code:
public class NioClient { public static void main(String[] args) throws IOException { SocketChannel open = SocketChannel.open(); open.bind(new InetSocketAddress("127.0.0.1", 1024)); ByteBuffer wrap = ByteBuffer.wrap("This is what goes to the server".getBytes()); open.write(wrap); //Without an end tag, you'll get stuck in a dead loop open.shutdownOutput(); System.out.println("Data has been passed to the server"); ByteBuffer allocate = ByteBuffer.allocate(1024); int len; while ((len=open.read(allocate))!=-1){ allocate.flip(); System.out.println(new String(allocate.array(),0,len)); allocate.clear(); } open.close(); } }
Selector for NIO
Role: Monitor channel status
Selector Selector Object
Key bound to SelectionKey
Selectable Channel Selector Channel
SocketChannel
ServerSocketChannel
A server corresponds to a client
1. Open a server-side channel
2. Bind the corresponding port
3. Channel is blocked by default and needs to be set to non-blocked
4. Open a selector
5. If a client connects, the selector tells the server channel to connect
6. Inside a service-side channel, creating a client channel is an extension of the client channel
7. If the client channel passes data, the selector tells the extended client channel to transfer it
If a server has multiple clients to connect, it will depend on which server channel is ready and who will connect.
Selector Overwrite Server
Selector Monitors Client Channels
Selector Monitor Server Channel
Selector monitors client extension channels
Client Code:
public class NioClient { public static void main(String[] args) throws IOException { SocketChannel open = SocketChannel.open(); open.bind(new InetSocketAddress("127.0.0.1", 1024)); ByteBuffer wrap = ByteBuffer.wrap("This is what goes to the server".getBytes()); open.write(wrap); //Without an end tag, you'll get stuck in a dead loop open.shutdownOutput(); System.out.println("Data has been passed to the server"); ByteBuffer allocate = ByteBuffer.allocate(1024); int len; while ((len=open.read(allocate))!=-1){ allocate.flip(); System.out.println(new String(allocate.array(),0,len)); allocate.clear(); } open.close(); } }
Server side code:
public class NioServer { public static void main(String[] args) throws IOException { //Open Service End Channel ServerSocketChannel opServerSocketChannelen = ServerSocketChannel.open(); //2. Select Port ServerSocketChannel bind = opServerSocketChannelen.bind(new InetSocketAddress(1024)); //Set to non-blocking opServerSocketChannelen.configureBlocking(false); //Select a selector //Selector - Selector //SelectionKey -- the key returned after binding the channel //Selectable Channel - A channel that can use a selector Selector selector = Selector.open(); //Binding Selector and Server-side Channels opServerSocketChannelen.register(selector,SelectionKey.OP_ACCEPT); //The selector monitors the status of the client channel while (true){ //The selector monitors the state of the client //The return value indicates how many clients are connected at this time int count = selector.select(); if (count!=0){ System.out.println("There are clients to connect"); //Traverse all service-side channels to see which ready number will connect Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()){ //neselectionKeyxt represents a token for each server at a time SelectionKey selectionKey = iterator.next(); if (selectionKey.isAcceptable()){ //A ready server-side channel can be obtained by tokens ServerSocketChannel channel = (ServerSocketChannel)selectionKey.channel(); //Extended Channel for Clients channel.accept(); //Change client's extension channel to non-blocking channel.configureBlocking(false); channel.register(selector,SelectionKey.OP_READ); //When the client comes to connect, all steps are completed }else if (selectionKey.isAcceptable()){ //Current channel and ready to read (Extended Channel) SocketChannel channel = (SocketChannel) selectionKey.channel(); ByteBuffer allocate = ByteBuffer.allocate(1024); //channel.read(allocate); int len; while ((len=channel.read(allocate))>0){ allocate.flip(); System.out.println(new String(allocate.array(),0,len)); allocate.clear(); } //Writeback data to client channel.write(ByteBuffer.wrap("This is data written back to the client".getBytes(StandardCharsets.UTF_8))); channel.close(); } iterator.remove(); } } } } }