Step by step, I learned the knowledge of JUC concurrent programming before, and now I finally come to Java IO network programming. It's difficult.
1, BIO introduction
Introduction: with the development of technology, two or more programs must interact, so it provides an end-to-end communication, which is equivalent to a encapsulation of the transport layer. For developers, it hides the details of transmission, abstracts these fixed "routines" and provides an end-to-end communication, which can make us focus more on business development. BIO is just one of them.
Java BIO (old) is the traditional Java I/O programming. Its related classes and interfaces are in java.io. In addition, Java BIO is synchronous and blocking (traditional blocking). The server implementation mode is one thread connected, that is, when the client has a connection request, the server needs to start a thread for processing. Low efficiency and easy to waste resources.
Blocking and non blocking:
Blocking and non blocking refer to whether to perform an operation, wait until the operation is over, or return immediately.
For example, the waiter of the restaurant orders for the user. When a user orders, the waiter gives the menu to the background chef. At this time, there are two ways:
- The first kind: wait at the food window until the cook finishes frying the food and sends it to the window, and then the waiter sends the food to the user; (blocking mode)
- Second: come to the window later and ask the chef if a dish is ready? If you don't deal with other things first, you'll ask again later; (non blocking)
2, BIO model
Process analysis:
- First, you need to start a ServerSocket server for the client to connect
- Then start the ClientSocket client to connect and communicate with the server. (Note: by default, each client and server communicates with a separate thread, whether used or not)
- After the client sends a request, it will first ask the server whether there can be a thread response. There are two results:
- If there is a thread response, the client will block and wait for the request to end before continuing execution;
- If there is no thread response, it will wait for a response or be rejected directly
3, Code case
1) Case:
We use the BIO model to write a server, listen to port 8888, and start a thread to communicate with it when there is a client connection.
Programming ideas:
- Create a thread pool
- Create a ServerSocket object server socket to wait for incoming requests over the network.
- If there is a client connection, create a thread to communicate with it (write a separate method)
- Obtain the Socket object for connection communication
- Write a handler method to communicate with the client and read the information sent by the client
package com.crush.bio; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.*; /** * @Author: crush * @Date: 2021-08-23 11:51 * version 1.0c */ public class BioServer { public static void main(String[] args) throws Exception { //1. Create a thread pool ExecutorService newCachedThreadPool = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); //2. Create ServerSocket ServerSocket serverSocket = new ServerSocket(8888); System.out.println("The server started"); while (true) { System.out.println("Thread information id = " + Thread.currentThread().getId() + "name = " + Thread.currentThread().getName()); //Listen and wait for the client to connect System.out.println("Waiting for connection...."); //3. Listen for a connection to this socket and accept it. This method blocks until a connection is established. final Socket socket = serverSocket.accept(); System.out.println("Connect to a client"); //4. Create a thread and communicate with it (write a separate method) newCachedThreadPool.execute(() -> { //Can communicate with clients handler(socket); }); } } /** * Write a handler method to communicate with the client and read the information sent by the client * @param socket */ public static void handler(Socket socket) { try { System.out.println("Thread information id = " + Thread.currentThread().getId() + "name = " + Thread.currentThread().getName()); byte[] bytes = new byte[1024]; //Get input stream through socket InputStream inputStream = socket.getInputStream(); //Cyclic reading of data sent by the client while (true) { System.out.println("Thread information id = " + Thread.currentThread().getId() + "name = " + Thread.currentThread().getName()); System.out.println("read...."); int read = inputStream.read(bytes); if (read != -1) { //Output data sent by client System.out.println(new String(bytes, 0, read)); } else { break; } } } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("Close and client Connection of"); try { socket.close(); } catch (Exception e) { e.printStackTrace(); } } } }
This is a classic per connection per thread model. The main reason for using multithreading is that the three main functions of socket.accept(), socket.read(), and socket.write() are synchronously blocked. When a connection is processing I/O, the system is blocked. If it is a single thread, it will hang there; But the CPU is released. If you turn on multithreading, you can let the CPU handle more things.
2) Test steps:
-
Open the cmd command and enter telnet localhost 8888
-
You will enter the telnet page
-
Then press CTRL +] in the telnet command window
-
The send message command is send message
-
console output
client:
I also wrote it on the client 😁
package com.crush.bio; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; public class BIOEchoClient { public static void main(String[] args) throws Exception{ Socket client = new Socket("localhost",8888); PrintStream out = new PrintStream(client.getOutputStream()); boolean flag = true; while (flag){ Scanner scanner = new Scanner(System.in); String inputData = scanner.nextLine().trim(); out.println(inputData); if ("byebye".equalsIgnoreCase(inputData)){ flag = false; System.out.println("Say goodbye to the client!!!"); } } client.close(); } }
I won't say this test. It's quite simple.
3) Possible problems
We use the telnet command to test. By default, Windows is turned off, and the same problem will occur as me.
Opening method: open the control panel, click the program, and then click this to select.
4, Defects of BIO
The biggest defect of BIO is that each request needs to create an independent thread for connection communication, which will cause the following problems:
- When the number of concurrent threads rises to a large level, a large number of threads need to be created to process, which is easy to cause great pressure on the system. Secondly, creating too many threads and destroying too many threads occupy a large amount of system resources.
- If the current thread task is small and short after the connection is established, and then there is no data to Read, the thread will always block the Read operation, resulting in a waste of resources.
5, Talk to yourself
Recently, in the continuous update, if you feel helpful and interested, pay attention to me. Let's study and discuss together.
Being full of curiosity and understanding the importance of thinking is a positive driving force to support my continuous learning. I hope you can also like programming! 😁
Love life, enjoy life!!! No matter where you are, no matter how hard life is at this time, remember to love life!!! I believe there will always be light.
Hello, I'm blogger Ning Zaichun, a small seed on the Java learning road. I also hope to take root and grow into a big tree in the sky one day.
I hope to encourage you 😁
We: when we meet at parting, we have achieved everything.