zoukankan      html  css  js  c++  java
  • NIO

     1 /**
     2  * Server,NIO本质是非阻塞。 Selector SelectionKey ServerSocketChannel SocketChannel
     3  */
     4 public class MyServerSocketChannel {
     5     public static void main(String[] args) {
     6         Selector sel = null ;
     7         //
     8         try {
     9             sel = Selector.open();                                            //开启挑选器
    10             ServerSocketChannel ssc = ServerSocketChannel.open();            //开启服务器SocketChannel
    11             InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 8888);
    12             ssc.bind(addr);
    13             ssc.configureBlocking(false);                                    //配置非阻塞
    14             ssc.register(sel, SelectionKey.OP_ACCEPT);                        //***** 在挑选器中注册ssc通道 *****
    15         } catch (Exception e) {
    16             e.printStackTrace();
    17         }
    18         
    19         SocketChannel sc0 = null;
    20         ByteBuffer buf = null;
    21         // CharBuffer cbuf = CharBuffer.allocate(1024);
    22         while (true) {
    23             // 开始挑选
    24             try {
    25                 sel.select();                                                //开始挑选
    26             } catch (Exception e) {
    27                 e.printStackTrace();
    28             }
    29             // 处理发生的事件
    30             Set<SelectionKey> keys = sel.selectedKeys();                    //获得selectedKey集合
    31             for (SelectionKey key : keys) {
    32                 try {
    33                     // 是否是accept事件
    34                     if (key.isAcceptable()) {
    35                         // 得到服务器通道
    36                         ServerSocketChannel ssc0 = (ServerSocketChannel) key.channel();//ssc0和ssc是同一个服务器通道,只是不同的引用
    37                         // 接受客户端连接,返回SocketChannel
    38                         sc0 = ssc0.accept();
    39                         System.out.println(getClientInfo(sc0.socket()) + " : 上线了!" );
    40                         // 注册非阻塞
    41                         sc0.configureBlocking(false);
    42                         // 在挑选器中注册新产生的SocketChannel
    43                         sc0.register(sel, SelectionKey.OP_READ | SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT);
    44                         //
    45                     }
    46                     // 可以读取数据了。
    47                     if (key.isReadable()) {
    48                         // 得到SocketChannel
    49                         sc0 = (SocketChannel) key.channel();
    50                         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    51 
    52                         //
    53                         buf = ByteBuffer.allocate(1024);
    54                         // 读取客户端发送的数据
    55                         while (sc0.read(buf) != 0) {
    56                             buf.flip();
    57                             baos.write(buf.array(), 0, buf.limit());
    58                             buf.clear();                        //重置buf
    59                         }
    60                         // 构造缓冲区,写回去client.
    61                         String str = "hello : " + new String(baos.toByteArray());
    62                         // 输出内容
    63                         System.out.println(getClientInfo(sc0.socket()) + str);
    64                         
    65                         //回传信息
    66                         buf = ByteBuffer.allocate(str.getBytes().length);
    67                         buf.put(str.getBytes());
    68                         buf.flip();
    69                         sc0.write(buf);
    70                         buf.clear();
    71                     }
    72                 } catch (Exception e) {
    73                     //从selector注销通道
    74                     key.cancel();
    75                     //
    76                     if(key.channel() instanceof SocketChannel){
    77                         Socket s = ((SocketChannel)key.channel()).socket();
    78                         System.out.println(getClientInfo(s) + " : 下线了!");
    79                     }
    80                 }
    81             }
    82             keys.clear();
    83         }
    84     }
    85 
    86     /**
    87      * 获得客户端信息
    88      */
    89     private static String getClientInfo(Socket socket) {
    90         InetSocketAddress addr = (InetSocketAddress) socket.getRemoteSocketAddress();
    91         String ip = addr.getAddress().getHostAddress();
    92         String port = addr.getPort() + "";
    93         return "[" + ip + ":" + port + "] ";
    94     }
    95 }

    2、客户端

     1 /**
     2  * 客户端
     3  */
     4 public class MyClientSocketChannel {
     5     public static void main(String[] args) throws Exception {
     6         Selector sel = Selector.open();                //挑选器
     7         SocketChannel sc = SocketChannel.open();    //开启通道
     8         InetSocketAddress addr = new InetSocketAddress("localhost", 8888);//服务器地址
     9         sc.connect(addr);                            //连接
    10         
    11         sc.configureBlocking(false);                //*****非阻塞模式
    12         sc.register(sel, SelectionKey.OP_READ);        //注册read事件
    13         
    14         new Sender(sc).start();                        //开启线程发送消息
    15         
    16         //
    17         ByteBuffer buf = ByteBuffer.allocate(1024);
    18         //开始挑选
    19         while(true){
    20             sel.select();
    21             ByteArrayOutputStream baos = new ByteArrayOutputStream();
    22             while(sc.read(buf) != 0){
    23                 buf.flip();
    24                 baos.write(buf.array(),0,buf.limit());
    25                 buf.clear();
    26             }
    27             String str = new String(baos.toByteArray());
    28             System.out.println(str);
    29         }
    30     }
    31 }

    3、多线程分支读取数据的输入

     1 /**
     2  * 发送器线程
     3  */
     4 public class Sender extends Thread{
     5     private SocketChannel sc ;
     6     public Sender(SocketChannel sc){
     7         this.sc = sc ;
     8     }
     9     public void run() {
    10         try {
    11             //读取console内容,写入到sc
    12             BufferedReader br = new BufferedReader(
    13                     new InputStreamReader(System.in));
    14             String line = null ;
    15             ByteBuffer buf = null ;
    16             while((line = br.readLine()) != null){
    17                 buf = ByteBuffer.allocate(1024);
    18                 buf.put(line.getBytes());
    19                 buf.flip();
    20                 sc.write(buf);
    21                 buf.clear();
    22             }
    23         } catch (Exception e) {
    24             e.printStackTrace();
    25         }
    26     }
    27 }

     2、

     1 public class MyServer {
     2     public static void main(String[] args) {
     3     //创建挑选器
     4         try {
     5             Selector sel = Selector.open();
     6         //获取服务器通道
     7             ServerSocketChannel ssc = ServerSocketChannel.open();
     8         //设置非阻塞模式
     9             ssc.configureBlocking(false);
    10         //绑定地址
    11             ssc.socket().bind(new InetSocketAddress("localhost", 8888));
    12             
    13         //在挑选器中注册通道,指定感兴趣事件
    14             ssc.register(sel, SelectionKey.OP_ACCEPT);
    15         
    16             while(true){
    17                 //不断地挑选
    18                 sel.select();
    19                 //被挑选出的key的集合
    20                 Set<SelectionKey> keys = sel.selectedKeys();
    21                 Iterator<SelectionKey> it = keys.iterator();
    22                 
    23                 while(it.hasNext()){
    24                     SelectionKey key = it.next();
    25                     if(key.isAcceptable()){
    26                         SocketChannel sc = ssc.accept();
    27                         System.out.println("有人连进来了");
    28                         sc.configureBlocking(false);
    29                         sc.register(sel, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
    30                         System.out.println("有人注册了");
    31                     }
    32                     if(key.isReadable()){
    33                         SocketChannel sc = (SocketChannel) key.channel();
    34                         System.out.println(readStrFromChannel(sc));
    35                     }
    36                     if(key.isWritable()){
    37                         ByteBuffer buf = ByteBuffer.allocate(1024);
    38                         buf.put("hello world".getBytes());
    39                         buf.flip();
    40                         SocketChannel sc = (SocketChannel) key.channel();
    41                         sc.write(buf);
    42                         key.cancel();//取消连接
    43                     }
    44                     it.remove();
    45                 }
    46                 //keys.clear();
    47             }
    48         } catch (Exception e) {
    49             
    50             
    51         }
    52     }
    53     private static String readStrFromChannel(SocketChannel sc) {
    54         ByteArrayOutputStream bos = new ByteArrayOutputStream();
    55         ByteBuffer buffer = ByteBuffer.allocate(1024);
    56         try {
    57             while(sc.read(buffer)>0){
    58                 buffer.flip();
    59                 bos.write(buffer.array(), 0, buffer.limit());
    60             }
    61             return new String(bos.toByteArray());
    62         } catch (IOException e) {
    63             e.printStackTrace();
    64         }
    65         return null;
    66     }
    67 }
     1 public class MyClient {
     2 
     3     public static void main(String[] args) {
     4         try {
     5             Selector sel = Selector.open();
     6             SocketChannel sc = SocketChannel.open();
     7             sc.configureBlocking(false);
     8             SelectionKey key = sc.register(sel, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
     9             sc.connect(new InetSocketAddress("localhost", 8888));
    10             int i=0;
    11             while (true) {
    12                 sel.select();
    13                 // 挑选器中最多只有一个对象
    14                 if (sel.selectedKeys().isEmpty()) {
    15                     continue;
    16                 }
    17                 if (key.isConnectable()) {
    18                     sc.finishConnect();
    19                 }
    20                 if (key.isReadable()) {
    21                     String src=(readStrFromChannel(sc));
    22                     if(src !=null){
    23                         System.out.println(src);
    24                     }
    25                 }
    26                 if(key.isWritable()){
    27                     ByteBuffer buffer = ByteBuffer.allocate(11);
    28                     buffer.put("hello wokd".getBytes());
    29                     buffer.flip();//重新定位指针,用于写
    30                     sc.write(buffer);
    31                 }
    32                 i++;
    33             }
    34 
    35         } catch (Exception e) {
    36             e.printStackTrace();
    37         }
    38     }
    39 
    40     private static String readStrFromChannel(SocketChannel sc) {
    41         ByteArrayOutputStream bos = new ByteArrayOutputStream();
    42         ByteBuffer buffer = ByteBuffer.allocate(20);
    43         try {
    44             if(sc.read(buffer)>0){
    45                 buffer.flip();
    46                 bos.write(buffer.array(), 0, buffer.limit());
    47                 //buffer.clear();
    48             }
    49             return new String(bos.toByteArray());
    50         } catch (IOException e) {
    51             e.printStackTrace();
    52         }
    53         return null;
    54     }
    55 
    56 }
  • 相关阅读:
    VisualSVN-Server windows 版安装时报错 "Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details."
    Pytest 单元测试框架之初始化和清除环境
    Pytest 单元测试框架入门
    Python(email 邮件收发)
    Python(minidom 模块)
    Python(csv 模块)
    禅道简介
    2020年最好的WooCommerce主题
    Shopify网上开店教程(2020版)
    WooCommerce VS Magento 2020:哪个跨境电商自建站软件更好?
  • 原文地址:https://www.cnblogs.com/yihaifutai/p/6790548.html
Copyright © 2011-2022 走看看