One, blocking IO and non-blocking IO
Linux Network IO Model (5 types)
(1) Blocking IO model
All file operations are blocked, and in the case of a socket interface, call recvfrom in process space, which is not returned until the packet arrives and is copied to the application process buffer or an error occurs, waiting (blocking). Model
(2) Non-blocking IO model
Recvfrom from the application layer to the kernel, if the buffer does not have data, directly return a ewouldblock error, repeatedly polling check this state to see if there is data coming.
(3) IO multiplexing model
Linux improves select/poll by passing one or more fd (file descriptor) to a Select or poll system call, blocking the select operation and detecting if multiple FD is in the ready state. Select/poll Sequential Scan FD is ready, and the number of supported FD is limited. Linux also provides a epoll system call that uses an event-driven approach instead of sequential scanning for higher performance. When FD is ready, the callback function rollback immediately.
(4) Signal-driven IO model
First, the socket signal-driven IO function is opened, and a signal processing function is executed through the system call Sigaction, the function returns immediately and the process continues to work, it is non-blocking. When the data is ready, a sigio signal is generated for the process, and the signal callback notifies the application to call Recfrom to read the data and notifies the main loop function to process the data.
(5) Asynchronous IO Model
Tells the kernel to initiate an action to let the kernel notify us when the entire operation is complete, including copying data from the kernel to the user's own buffer area. The main difference between it and the signal driver is that the signal-driven IO is told by the kernel when we start an IO operation, and the asynchronous IO model informs us when the IO operation has been completed. :
IO multiplexing Applications:
By reusing multiple IO blocking to a single select block, the system can handle multiple client requests in a single thread. Compared to traditional multithreaded models, the biggest advantage is that the system overhead is small and no additional processes or threads need to be created. The main application scenarios are as follows:
(1) The server needs to handle multiple sockets in the listening State or connection state at the same time
(2) The server needs to handle multiple network protocol sockets simultaneously
Linux final selection Epoll supports IO multiplexing system calls with the following advantages:
(1) Support for a process open socket descriptor (FD) unrestricted (select single thread default 1024 too few, Epoll only limited operating system maximum file handle, 1GB memory machine about 100,000 handles)
(2) The IO efficiency does not decrease linearly with the number of FD (only the "active" Socke do the T operation, and the active socket is actively calling the callback function)
(3) Use mmap to accelerate kernel and user space message delivery (same piece of memory, avoid unnecessary duplication)
(4) Simple API: Create Epoll descriptor, add listener event, block wait for listener event, close Epoll descriptor, etc.
Ii. examples of blocking IO (combined with thread pool)
1. Service-side package Com.xbai.io;import Java.io.ioexception;import Java.net.serversocket;import java.net.socket;import Com.xbai.executor.timeserverhandlerexecutepool;import Com.xbai.handler.timeserverhandler;public Class timeserverexecutor {public static void main (string[] args) throws IOException {int port = 8080; if (args!=null && args.length >0) {try {port = integer.valueof (Args[0]); }catch (Exception e) {//Todo:handle Exception}} serversocket server =null; try {server =new ServerSocket (port); System.out.println ("The time server is started in port:" + port); Timeserverhandlerexecutepool singleexecutor =new Timeserverhandlerexecutepool (50,10000); while (true) {Socket socket = server.accept (); Singleexecutor.execute (new Timeserverhandler (socket)); }}finally {if (server!=null) {System.out.println ("The time server Closed"); server.clOSE (); Server =null; } } }}
//2. Service Thread Pool Package Com.xbai.executor;import Java.util.concurrent.arrayblockingqueue;import Java.util.concurrent.executorservice;import Java.util.concurrent.threadpoolexecutor;import Java.util.concurrent.timeunit;public Class Timeserverhandlerexecutepool {private Executorservice executor; Public timeserverhandlerexecutepool (int maxpoolsize,int queuesize) {executor =new threadpoolexecutor ( Runtime.getruntime (). Availableprocessors (), Maxpoolsize,120l,timeunit.seconds, new Arrayblockingqueue (QueueSiz e));///thread pool to perform tasks blocked into a queue, its internal mechanism is waiting to wake the producer and consumer threads, there is a production can wake up a consumption, to see the source of the thread pool principle} public void execute (Runnable task) {executor. Execute (Task); }}
3. Server-side processor package Com.xbai.handler;import Java.io.bufferedreader;import Java.io.ioexception;import Java.io.inputstreamreader;import Java.io.outputstreamwriter;import Java.io.printwriter;import Java.net.Socket; Import Java.sql.date;public class timeserverhandlerimplements runnable{private socketsocket; Public Timeserverhandler (socket socket) {this.socket = socket; } @Override public void Run () {//TODO auto-generated method stub bufferedreader br =null; PrintWriter PW =null; try {br =new BufferedReader (New InputStreamReader (Socket.getinputstream ())); PW =new PrintWriter (Socket.getoutputstream (), true); String Curtime =null; String msg =null; while (true) {msg = Br.readline (); if (msg ==null) {break; } System.out.println ("The Time server received order:" + msg); Curtime = "Query time order". Equalsignorecase (msg)? New Date (System.currenttimemillis ()). ToString (): "BAd order "; Pw.println (curtime);//If you do not write println here, you cannot insert line breaks, there is no readline, blocking, unable to get data}}catch (IOException e) {if (br!=null) {try {br.close (); }catch (IOException E1) {//TODO auto-generated catch block E1.printstacktrace (); }} if (pw!=null) {pw.close (); PW =null; } if (socket!=null) {try {socket.close (); }catch (IOException E1) {//TODO auto-generated catch block E1.printstacktrace (); } socket =null; } } }}
4. Client code package Com.xbai.io;import Java.io.bufferedreader;import Java.io.ioexception;import Java.io.inputstreamreader;import Java.io.printwriter;import Java.net.socket;import java.net.UnknownHostException; public class Timeclient {public static void main (string[] args) {int port = 8080; if (args!=null && args.length >0) {try {port = integer.valueof (Args[0]); }catch (Exception e) {//Todo:handle Exception}} socket socket =null; BufferedReader BR =null; PrintWriter PW =null; try {socket =new socket ("localhost", port); BR =new BufferedReader (New InputStreamReader (Socket.getinputstream ())); PW =new PrintWriter (Socket.getoutputstream (), true); PW.PRINTLN ("Query Time Order"); SYSTEM.OUT.PRINTLN ("Send Order Succeed"); String resp = Br.readline (); System.out.println ("Now is:" + resp); }catch (IOException e) {//TODO auto-generated catch block e.printsTacktrace (); }finally{if (pw!=null) {pw.close (); PW =null; } if (br!=null) {try {br.close (); }catch (IOException e) {//TODO auto-generated catch block E.printstacktrace (); } BR =null; } if (socket!=null) {try {socket.close (); }catch (IOException e) {//TODO auto-generated catch block E.printstacktrace (); } socket =null; } } }}
Netty practice and the principle of NIO