Java Network Programming
1. Socket programming
Socket: a class that encapsulates information such as the port number, IP address, and computer name. Through Socket, we can communicate with a remote computer.
Network Communication Model
C/S Client/Server
The client operates on the user's computer. The client is a unique program that provides unique functions, connects to the server for communication, and who initiates the connection and who is the user.
The server usually waits for a client connection to provide functional services and communicate with them.
B/S
Fixed the client and communication agreement and C/S structure.
Communication Protocol: the essence of computer communication is to send and receive bytes from each other. The communication protocol is used to send and receive bytes in a certain format.
/* ** Create a client Socket * Socket Client class *. During the construction, the server attempts to connect to the client based on the given server IP address and server port number */try {System. out. println ("START connection"); Socket socket = new Socket ("172.16.3.33", 8088); System. out. println ("connection to server successful! ");/*** A set of input and output streams that communicate with the server can be obtained through the socket. * We can encapsulate the input and output streams to read and write information conveniently. * Two low-level stream byte streams are obtained through the socket) */InputStream in = socket. getInputStream (); OutputStream out = socket. getOutputStream ();/*** send characters to the server and convert the character output stream to the buffer character output stream */PrintWriter pw = new PrintWriter (out); pw. println ("Hello server! "); Pw. flush ();/*** receives the string sent by the server, packaged as a buffer character input stream */BufferedReader reader = new BufferedReader (new InputStreamReader (in )); // read the information sent back by the Server String info = reader. readLine (); System. out. println ("server:" + info);} catch (IOException e) {// e. printStackTrace ();} /*** server * Open socket on the server side and wait for the client to connect * the Socket name on the server side is ServerSocket * The Service port number must be specified when ServerSocket * is created */public static void main (String [] args) {try {System. out. println ("ddd D "); ServerSocket server = new ServerSocket (8050);/*** listener port * Wait for client connection method accept () * This method is a blocking method, if you know that a client is connected to this method, the returned result is the socket of the current client. * We can know the client's ip address and other information. ** The accept () method can be called repeatedly */System. out. println ("started, waiting for connection"); Socket client = server. accept (); System. out. println ("A client Connected to me");/*** obtain the information of the client from the input stream through socket */InputStream in = client. getInputStream (); OutputStream out = client. getOutputStream (); BufferedReader reader = new BufferedReader (new InputStreamReader (in); System. out. println ("client:" + reader. readLine (); // send the message PrintWriter pw = new PrintWriter (out) to the client. pw. println ("Hello client"); pw. flush ();} catch (IOException e) {// e. printStackTrace ();}}
2. multi-thread Socket
Server multithreading:
The server receives the access from the client in an infinite loop, and each connection is connected to an instance of a new Socket.
Create an independent thread for each client connection to process customer requests.
Public static void main (String [] args) {try {ServerSocket server = new ServerSocket (8088); System. out. println ("started, waiting for connection"); while (true) {Socket client = server. accept (); if (client = null) continue; System. out. println ("successfully connected to the client" + client. getInetAddress (). getHostAddress (); Handler handler = new Handler (client); // submit it to the Thread to process Thread t = new Thread (handler); t. start () ;}} catch (IOException e) {}}/*** the communication thread with the client * is responsible for communicating with the client of a specific socket * Each thread instance is responsible for communicating with one client */private static class Handler implements Runnable {/*** the client socket to be communicated by the current thread */private Socket client; public Handler (Socket client) {this. client = client;} public void run () {try {/** obtain client information through socket */InputStream in = this. client. getInputStream (); BufferedReader reader = new BufferedReader (new InputStreamReader (in);/** read client information through endless loops */while (true) {if (reader. readLine () = null) return; System. out. println ("client" + this. client. getInetAddress (). getHostAddress () + ":" + reader. readLine () ;}} catch (Exception e ){}}}
3. Thread Pool
The preceding frequent thread creation and thread destruction consume a lot of resources and performance.
You can create some empty threads and save them. When a task needs to be executed concurrently, we take out an empty thread to run the task. After the task is completed, wait for the next task to be allocated.
In this way, we only use the threads we created from the beginning and the end, and can reuse them to save performance overhead.
JDK provides the thread pool manager ExecutorService
Use the static method of the Executors class to create several thread pools with different implementations.
Executors. newCachedThreadPool (); creates a cache thread pool. When there is a task, it checks whether there are free threads in the thread pool. If yes, It is used. If not, a new thread is created. Threads that have not been used for a long time will be automatically recycled.
Executors. newFixedThreadPool (int threads); creates a reusable thread pool with a fixed number of threads.
Executors. newScheduledExecutor (); creates a thread pool with only one thread. It can execute a thread task after a specified delay.
Executors. newSingleThreadExecutor (); creates a single-threaded thread pool, which is equivalent to parameter 1 passed in when the Exceutors. newFixedThreadPool method is used. A task queue is maintained.
/*** Create a thread pool with 50 threads */ExecutorService threadPool = Executors. newFixedThreadPool (50); try {ServerSocket server = new ServerSocket (8088); System. out. println ("started, waiting for connection");/** start the forwarding message Thread */SendMessageHandler sHandler = new SendMessageHandler (); Thread sendTh = new Thread (sHandler); sendTh. start (); while (true) {Socket client = server. accept (); System. out. println ("successfully connected to the client" + client. getInetAddress (). getHos TAddress (); Handler handler = new Handler (client); // submit it to the thread for processing/*** run the Runnable task that requires concurrency) submit it to the thread pool * assign it a blank thread to run the task * If the thread is working, publish it until there is a free thread. */ThreadPool.exe cute (handler); // Thread t = new Thread (handler); // t. start () ;}} catch (IOException e ){}
4. Dual-end queue
It is implemented by two queues internally, and they exchange access work. In this way, at least two threads can simultaneously perform access operations. But synchronization is still required for both threads to store or fetch data at the same time.
However, it is faster than a single queue to implement thread security.
BlockingDeque dual-end queue
Implementation:
1) The constructor of the ArrayBlockingDeque class requires an integer to represent the length of the current queue. Therefore, this is a fixed-size dual-end queue. The access principle is FIFO first-in-first-out.
When an element calls offline to store data in the queue, if the queue is full, you can set a delay wait. If the delay wait is exceeded, the storage failure will be returned.
2) LinkedBlockingDeque. The length is not fixed. As the number of elements increases, the maximum value can reach Integer. MAX_VALUE. The overload constructor can input an Integer to change it to a queue with a fixed length.
3) PriorityBlockingDeque, which is similar to LinkedBlockingDeque, is obtained after being sorted by nature.
4) SynchronousQueue Special Double-end queue access steps are required, must be stored once, alternate.
Example:
Server
/*** Create a static set to protect the number of input streams of all clients * Note: Because this set is used by multiple threads, the set is safe. */Static Vector <PrintWriter> allOut = new Vector <PrintWriter> ();/** Message Queue */static BlockingDeque <String> msgQueue = new LinkedBlockingDeque <String> (); public static void main (String [] args) {/*** creates a thread pool with 50 */ExecutorService threadPool = Executors. newFixedThreadPool (50); try {ServerSocket server = new ServerSocket (8088); System. out. println ("starting, waiting for connection");/** start the message forwarding thread */SendMessageHandler sHand Ler = new SendMessageHandler (); Thread sendTh = new Thread (sHandler); sendTh. start (); while (true) {Socket client = server. accept (); System. out. println ("successfully connected to the client" + client. getInetAddress (). getHostAddress (); Handler handler = new Handler (client); // submit it to the thread for processing/*** run the Runnable task that requires concurrency) submit it to the thread pool * assign it a blank thread to run the task * If the thread is working, publish it until there is a free thread. */ThreadPool.exe cute (handler); // Thread t = new Thread (handler); // t. start () ;}} catch (IOException e) {}}/*** the communication thread with the client * is responsible for communicating with the client of a specific socket * Each thread instance is responsible for communicating with one client */private static class Handler implements Runnable {/*** the client socket to be communicated by the current thread */private Socket client; public Handler (Socket client) {this. client = client;} public void run () {PrintWriter pw = null; try {/** obtain client information through socket */InputS Tream in = this. client. getInputStream (); BufferedReader reader = new BufferedReader (new InputStreamReader (in);/*** Save the output stream of the current client to the shared set */pw = new PrintWriter (client. getOutputStream (); allOut. add (pw);/** read client information through an infinite loop */while (true) {String str = reader. readLine ();/*** put the information into the Message Queue */if ("q ". equals (str) {client. close ();} msgQueue. offer (str);/*** arg1: Storage Element * arg2: latency time * arg3: delay time unit ** the following method Is to store elements in the queue, set a 5-second timeout, if the timeout has not been put into the queue this returns false */boolean tf = msgQueue. offer (str, 5, TimeUnit. SECONDS) ;}} catch (Exception e) {e. printStackTrace ();/*** throws an exception. We should delete the output stream of this client from the shared set * to tell other threads not to send messages again. */AllOut. remove (pw) ;}}/*** forwards a message * To a cyclic message queue. Each message is sent to the client through the input streams of all clients * to broadcast the message. */Public static class SendMessageHandler implements Runnable {public void run () {while (true) {/** send messages cyclically to each client every 50 ms */String str = null; while (str = msgQueue. poll ())! = Null) {// and msgQueue. poll ()! = Null/** get the output stream of all clients and output the string */for (PrintWriter pw: allOut) {pw. println (str); pw. flush () ;}try {Thread. sleep (50);} catch (InterruptedException e) {e. printStackTrace ();}}}}
Client:
Public static void main (String [] args) {/*** create a client Socket * Socket Client class *. During construction, the server attempts to connect to the client based on the given server IP address and server port number */try {System. out. println ("START connection"); Socket socket = new Socket ("172.16.3.14", 8088); System. out. println ("connection to server successful! "); // Start the message Thread readermshandler = new Thread (new ReadMessageHandler (socket. getInputStream (); readermsstream. start (); OutputStream out = socket. getOutputStream (); PrintWriter pw = new PrintWriter (out); BufferedReader reader = new BufferedReader (new InputStreamReader (System. in); while (true) {pw. println (reader. readLine (); pw. flush () ;}} catch (IOException e) {// e. printStackTrace () ;}}/*** this thread is used Read Information from the server. */Public static class ReadMessageHandler implements Runnable {private InputStream in; // read information from the server public ReadMessageHandler (InputStream in) {this. in = in;} public void run () {try {// convert a byte input stream to a buffer character input stream BufferedReader reader = new BufferedReader (new InputStreamReader (in); while (true) {System. out. println (reader. readLine () ;}} catch (Exception e) {e. printStackTrace ();}}}
Bytes.
This article from the "beautiful life needs to carefully record" blog, please be sure to keep this http://huing.blog.51cto.com/1669631/1295163