• 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

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

  • 相关阅读:
    Java
    Java
    Java
    Java
    Java
    Java
    Java
    Java
    JSON
    正则表达式
  • 原文地址:https://www.cnblogs.com/liuyangfirst/p/8763429.html
Copyright © 2020-2023  润新知