• 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 }
  • 相关阅读:
    js修改input的type属性问题(兼容所有浏览器,主要用于密码类的默认有提示文字的效果)
    让一个div始终固定在页面的某一固定位置的方法
    js在IE8+兼容String没有trim方法,写一个兼容ie8一下的浏览器的trim()方法
    js用new Object创建json数据
    js+php实现文件上传显示文件上传进度条的插件
    关于一个页面的tab切换整体页面刷新而tab标签处是同一个文件怎么做焦点的问题
    B树及2-3树的python实现
    二叉查找树转变为有序双向链表
    Django中的静态文件管理
    Django文档——Model中的ForeignKey,ManyToManyField与OneToOneField
  • 原文地址:https://www.cnblogs.com/yihaifutai/p/6790548.html
Copyright © 2020-2023  润新知