Article catalog
I Network communication of NIO combined with Scott
1.NIO channel client
- Client implementation steps
- Open channel
- Specify the IP and port number
- Write data
- Release resources
- Sample code
public class NIOClient { public static void main(String[] args) throws IOException { //1. Open the channel SocketChannel socketChannel = SocketChannel.open(); //2. Specify the IP and port number socketChannel.connect(new InetSocketAddress("127.0.0.1",10000)); //3. Write data ByteBuffer byteBuffer = ByteBuffer.wrap("NIO combination Scoket Network communication".getBytes()); socketChannel.write(byteBuffer); //4. Release resources socketChannel.close(); } }
2. NIO channel server
- NIO channel
Server channel
It is only responsible for establishing, not transmitting data
Client channel
Establish and transfer data to the server
buffer
The data sent by the client is in the buffer
The client channel created inside the server channel
Equivalent to an extension of the client channel used to transfer data
- Server implementation steps
Open a server channel
Bind the corresponding port number
The channel is blocked by default and needs to be set to non blocking
There is no guard at this time, so you need to often check whether there is a connection sent?
If a client is connected, create another client channel inside the server channel, which is equivalent to the extension of the client channel
Get the data passed by the client and put the data in the buffer byteBuffer1
Write back data to the client
Release resources
- Sample code
public class NIOServer { public static void main(String[] args) throws IOException { // 1. Open a server channel ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 2. Bind the corresponding port number serverSocketChannel.bind(new InetSocketAddress(10000)); // 3. The channel is blocked by default and needs to be set to non blocking //If true is passed, the channel is set to blocked channel Default value //If false is passed, the channel is set to a non blocking channel serverSocketChannel.configureBlocking(false); // 4. There is no guard at this time, so you need to often check whether there is a connection sent? while (true) { // 5. If a client is connected, create another client channel inside the server channel, which is equivalent to the extension of the client channel //At this time, the channel has been set to non blocking //Therefore, when calling the method, if there is a client to connect, a SocketChannel object will be created //If there is no client to connect when calling the method, it will return a null SocketChannel socketChannel = serverSocketChannel.accept(); //System.out.println(socketChannel); if(socketChannel != null){ // 6. The client passes the buffer to the server through the channel to the extension channel socketChannel // 7. The server creates an empty buffer to load data and output it ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //Get the passed data and put them into the byteBuffer buffer //Return value: //Positive number: indicates the number of valid bytes read this time //0: indicates that no valid bytes are read this time //-1: it means the end is read int len = socketChannel.read(byteBuffer); System.out.println(new String(byteBuffer.array(),0,len)); //8. Release resources socketChannel.close(); } } } }
3. NIO channel exercise
client
- Implementation steps
- Open channel
- Specify the IP and port number
- Write data
- Read data written back by the server
- Release resources
- Sample code
public class Clinet { public static void main(String[] args) throws IOException { // 1. Open the channel SocketChannel socketChannel = SocketChannel.open(); // 2. Specify the IP and port number socketChannel.connect(new InetSocketAddress("127.0.0.1",10000)); // 3. Write data ByteBuffer byteBuffer1 = ByteBuffer.wrap("NIO combination Scoket Network communication two-way communication version".getBytes()); socketChannel.write(byteBuffer1); // Manual write end flag socketChannel.shutdownOutput(); System.out.println("The data has been written to the server"); // 4. Read the data written back by the server ByteBuffer byteBuffer2 = ByteBuffer.allocate(1024); int len; while((len = socketChannel.read(byteBuffer2)) != -1){ byteBuffer2.flip(); System.out.println(new String(byteBuffer2.array(),0,len)); byteBuffer2.clear(); } // 5. Release resources socketChannel.close(); } }
- Server
Implementation steps
Open a server channel
Bind the corresponding port number
The channel is blocked by default and needs to be set to non blocking
There is no guard at this time, so you need to often check whether there is a connection sent?
If a client is connected, create another client channel inside the server channel, which is equivalent to the extension of the client channel
Get the data passed by the client and put the data in the buffer byteBuffer1
Write back data to the client
Release resources
- Sample code
public class Clinet { public static void main(String[] args) throws IOException { // 1. Open the channel SocketChannel socketChannel = SocketChannel.open(); // 2. Specify the IP and port number socketChannel.connect(new InetSocketAddress("127.0.0.1",10000)); // 3. Write data ByteBuffer byteBuffer1 = ByteBuffer.wrap("NIO combination Scoket Network communication two-way communication version".getBytes()); socketChannel.write(byteBuffer1); // Manual write end flag socketChannel.shutdownOutput(); System.out.println("The data has been written to the server"); // 4. Read the data written back by the server ByteBuffer byteBuffer2 = ByteBuffer.allocate(1024); int len; while((len = socketChannel.read(byteBuffer2)) != -1){ byteBuffer2.flip(); System.out.println(new String(byteBuffer2.array(),0,len)); byteBuffer2.clear(); } // 5. Release resources socketChannel.close(); } }
- Server
Implementation steps
Open a server channel
Bind the corresponding port number
The channel is blocked by default and needs to be set to non blocking
There is no guard at this time, so you need to often check whether there is a connection sent?
If a client is connected, create another client channel inside the server channel, which is equivalent to the extension of the client channel
Get the data passed by the client and put the data in the buffer byteBuffer1
Write back data to the client
Release resources
- Sample code
public class Sever { public static void main(String[] args) throws IOException { // 1. Open a server channel ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 2. Bind the corresponding port number serverSocketChannel.bind(new InetSocketAddress(10000)); // 3. The channel is blocked by default and needs to be set to non blocking serverSocketChannel.configureBlocking(false); // 4. There is no guard at this time, so you need to often check whether there is a connection sent? while(true){ // 5. If a client is connected, create another client channel inside the server channel, which is equivalent to the extension of the client channel SocketChannel socketChannel = serverSocketChannel.accept(); if(socketChannel != null){ System.out.println("At this time, there is a client to connect"); // 6. Get the data passed by the client and put the data in the buffer byteBuffer1 ByteBuffer byteBuffer1 = ByteBuffer.allocate(1024); //socketChannel.read(byteBuffer1); int len; //For buffers //If you get data from add data - > flip //If you get data from ---- > add data clear while((len = socketChannel.read(byteBuffer1)) != -1){ byteBuffer1.flip(); System.out.println(new String(byteBuffer1.array(),0,len)); byteBuffer1.clear(); } System.out.println("Finished receiving data,Ready to start writing data back to the client"); // 7. Write back data to the client ByteBuffer byteBuffer2 = ByteBuffer.wrap("Here you are!!".getBytes()); socketChannel.write(byteBuffer2); // 8. Release resources socketChannel.close(); } } } }
4. NIO channel practice optimization
- Existing problems When the client channel obtained by the server is read, if the end tag is not read, it will be blocked all the time
- Solution Set the client channel obtained internally by the server to non blocking
- Sample code
// client public class Clinet { public static void main(String[] args) throws IOException { SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("127.0.0.1",10000)); ByteBuffer byteBuffer1 = ByteBuffer.wrap("NIO combination Scoket Network communication".getBytes()); socketChannel.write(byteBuffer1); System.out.println("The data has been written to the server"); ByteBuffer byteBuffer2 = ByteBuffer.allocate(1024); int len; while((len = socketChannel.read(byteBuffer2)) != -1){ System.out.println("Client receives write back data"); byteBuffer2.flip(); System.out.println(new String(byteBuffer2.array(),0,len)); byteBuffer2.clear(); } socketChannel.close(); } } // Server public class Sever { public static void main(String[] args) throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress(10000)); serverSocketChannel.configureBlocking(false); while(true){ SocketChannel socketChannel = serverSocketChannel.accept(); if(socketChannel != null){ System.out.println("At this time, there is a client to connect"); // Set the client channel obtained internally by the server to non blocking socketChannel.configureBlocking(false); //Get the data passed by the client and put the data in the buffer byteBuffer1 ByteBuffer byteBuffer1 = ByteBuffer.allocate(1024); //socketChannel.read(byteBuffer1); int len; //For buffers //If you get data from add data - > flip //If you get data from ---- > add data clear while((len = socketChannel.read(byteBuffer1)) > 0){ System.out.println("The server receives and sends data"); byteBuffer1.flip(); System.out.println(new String(byteBuffer1.array(),0,len)); byteBuffer1.clear(); } System.out.println("Data reception completed,Ready to start writing data back to the client"); ByteBuffer byteBuffer2 = ByteBuffer.wrap("Here you are!!!".getBytes()); socketChannel.write(byteBuffer2); socketChannel.close(); } } } }
5. NIO selector
- summary The selector can monitor the status of the channel and multiplex


- Selector object
- Selector Selector object
- SelectionKey Bound key
- SelectableChannel
Channels that can use selectors
- SocketChannel
- ServerSocketChannel
6. NIO selector rewriting server
- Implementation steps
- Open a server channel
- Bind the corresponding port number
- The channel is blocked by default and needs to be set to non blocking
- Open a selector (doorman)
- Bind the selector to the server channel and monitor whether the server is ready
- If there is a client to connect, the uncle will traverse all the server channels. Whoever is ready will connect After connecting, create a client extension channel inside the server channel
- If the client transmits the data, the uncle will traverse all the extension channels. Who is ready and who will receive the data

- code implementation
// client public class Clinet { public static void main(String[] args) throws IOException { SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("127.0.0.1",10000)); ByteBuffer byteBuffer1 = ByteBuffer.wrap("NIO combination Scoket Network communication".getBytes()); socketChannel.write(byteBuffer1); System.out.println("The data has been written to the server"); ByteBuffer byteBuffer2 = ByteBuffer.allocate(1024); int len; while((len = socketChannel.read(byteBuffer2)) != -1){ System.out.println("Client receives write back data"); byteBuffer2.flip(); System.out.println(new String(byteBuffer2.array(),0,len)); byteBuffer2.clear(); } socketChannel.close(); } } // Server public class Server { public static void main(String[] args) throws IOException { //1. Open the server channel ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //2. Bind this channel to a port serverSocketChannel.bind(new InetSocketAddress(10000)); //3. Set the channel to non blocking serverSocketChannel.configureBlocking(false); //4. Open a selector //Selector --- selector // SelectionKey --- the token returned after binding the channel // SelectableChannel --- a channel that can use a selector Selector selector = Selector.open(); //5. Bind selector and server channel serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT); while(true){ System.out.println("11"); //The selector monitors the status of the client channel //6. The return value indicates how many clients are connected at this time int count = selector.select(); System.out.println("222"); if(count != 0){ System.out.println("There is a client to connect"); //7. It will traverse all server channels See who is ready, who is ready, let who connect //Get the tokens of all server channels, put them into a collection, and return the collection Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while(iterator.hasNext()){ //selectionKey indicates the token of each server channel in turn SelectionKey selectionKey = iterator.next(); if(selectionKey.isAcceptable()){ //A ready server channel can be obtained through a token ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel(); //Extended channel of client SocketChannel socketChannel = ssc.accept(); //Set the client extension channel to non blocking socketChannel.configureBlocking(false); socketChannel.register(selector,SelectionKey.OP_READ); //When the client connects, all the steps have been completed }else if(selectionKey.isReadable()){ //The current channel is ready for reading (extended channel) SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); ByteBuffer byteBuffer1 = ByteBuffer.allocate(1024); //socketChannel.read(byteBuffer1); int len; while((len = socketChannel.read(byteBuffer1)) > 0){ byteBuffer1.flip(); System.out.println(new String(byteBuffer1.array(),0,len)); byteBuffer1.clear(); } //Write back data to client socketChannel.write(ByteBuffer.wrap("Here you are!!!".getBytes())); socketChannel.close(); } iterator.remove(); } } } } }