Netty学习第五节实例进一步学习

概念理解:

          Netty是基于NIO的框架

 传统IO与NIO的区别:
      1、传统IO会造成阻塞点:
      2、单一的客户端处理消息
解决阻塞问题:建立线程池,达到收到一个消息就建立一个客户端交互
      3、 用socket实现长连接的缺陷:
             (1)消耗巨大
             (2)没建立一次交互,就会产生一个新的线程池连接,线程长时间被一个客户端占用 (举例:一个餐厅,每来一个客户,都分配一个单独的服务员,为其服务)
    传统socket可以做短连接的服务器。
    4、单线程情况下只能有一个客户端
    5、用线程池可以有多个客户端连接,但非常消耗性能
 
实战一:单线程实例
 1 package com.OIO;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.net.ServerSocket;
 5 import java.net.Socket;
 6 import java.util.concurrent.ExecutorService;
 7 import java.util.concurrent.Executors;
 8 /**
 9  * 传统socket服务端
10  * @author -琴兽-
11  *
12  */
13 public class OioServer {
14 
15     @SuppressWarnings("resource")
16     public static void main(String[] args) throws Exception {
17 
18 //        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
19         //创建socket服务,监听10101端口
20         ServerSocket server=new ServerSocket(10101);
21         System.out.println("服务器启动!");
22         while(true){
23             //获取一个套接字(阻塞)
24             final Socket socket = server.accept();
25             System.out.println("来个一个新客户端!");
26 
27             //业务处理
28             handler(socket);
29 
30             
31         }
32     }
33     
34     /**
35      * 读取数据
36      * @param socket
37      * @throws Exception
38      */
39     public static void handler(Socket socket){
40             try {
41                 byte[] bytes = new byte[1024];
42                 InputStream inputStream = socket.getInputStream();
43                 
44                 while(true){
45                     //读取数据(阻塞)
46                     int read = inputStream.read(bytes);
47                     if(read != -1){
48                         System.out.println(new String(bytes, 0, read));
49                     }else{
50                         break;
51                     }
52                 }
53             } catch (Exception e) {
54                 e.printStackTrace();
55             }finally{
56                 try {
57                     System.out.println("socket关闭");
58                     socket.close();
59                 } catch (IOException e) {
60                     e.printStackTrace();
61                 }
62             }
63     }
64 }
View Code

其中server.accept();和inputStream.read(bytes);会造成阻塞.

只能有一个客户端与服务端进行交互

window+R 进入cmd 命令界面,输入telnet 127.0.0.1 10101 进入创建连接,ctrl+] 进入命令界面,发送send hello 回车,就会向服务端发送数据.

解决方法,增加线程池操作

实例二:线程池实现连接交互

 1 package com.OIO;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.net.ServerSocket;
 6 import java.net.Socket;
 7 import java.util.concurrent.ExecutorService;
 8 import java.util.concurrent.Executors;
 9 
10 /**
11  * 传统socket服务端
12  *
13  * @author -琴兽-
14  */
15 public class OioServer {
16 
17     @SuppressWarnings("resource")
18     public static void main(String[] args) throws Exception {
19 
20         /**
21          * 创建线程池交互
22          */
23         ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
24 
25         //创建socket服务,监听10101端口
26         ServerSocket server = new ServerSocket(10101);
27         System.out.println("服务器启动!");
28         while (true) {
29             //获取一个套接字(阻塞)
30             final Socket socket = server.accept();
31             System.out.println("版本二 :*****来个一个新客户端!**********");
32 
33             newCachedThreadPool.execute(new Runnable() {
34                 @Override
35                 public void run() {
36                     //业务处理
37                     handler(socket);
38                 }
39             });
40             
41         }
42     }
43 
44     /**
45      * 读取数据
46      *
47      * @param socket
48      * @throws Exception
49      */
50     public static void handler(Socket socket) {
51         try {
52             byte[] bytes = new byte[1024];
53             InputStream inputStream = socket.getInputStream();
54 
55             while (true) {
56                 //读取数据(阻塞)
57                 int read = inputStream.read(bytes);
58                 if (read != -1) {
59                     System.out.println(new String(bytes,0,read));
60                 } else {
61                     break;
62                 }
63             }
64         } catch (Exception e) {
65             e.printStackTrace();
66         } finally {
67             try {
68                 System.out.println("socket关闭");
69                 socket.close();
70             } catch (IOException e) {
71                 e.printStackTrace();
72             }
73         }
74     }
75 }
View Code

可以实现多个客户端接入连接数据交互.但是却是每次建立一个线程,极大耗费资源

原文地址:https://www.cnblogs.com/liuyangfirst/p/8763429.html