zoukankan      html  css  js  c++  java
  • NIO概述及实例(时钟服务器)

    NIO,非阻塞IO,重点是非阻塞而不是异步!

    NIO的一般实现如下:

    package com.pt.nio;
    
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.Set;
    
    /**
     * @author panteng
     * @description 时钟服务器
     * @date 17-3-10.
     */
    public class NioServer {
        public static void main(String[] arges) throws Exception {
            char name = 'A';
            // 创建通道,并设置非阻塞
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);
            // 创建选择器,并为通道绑定感兴趣的事件
            Selector selector = Selector.open();
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT).attach("主监听通道");
            System.out.println("监听的channel Id:" + serverSocketChannel.hashCode());
            // 通道绑定端口号
            InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 4700);
            serverSocketChannel.socket().bind(inetSocketAddress);
            // 开始轮询通道事件
            while (true) {
                // 可以是阻塞,非阻塞,也可以设置超时
                int readyChannels = selector.selectNow();
                if (readyChannels > 0) {
                    Set<SelectionKey> readyKeys = selector.selectedKeys();
                    Iterator iterator = readyKeys.iterator();
                    while (iterator.hasNext()) {
                        SelectionKey readyKey = (SelectionKey) iterator.next();
                        iterator.remove();
                        if (readyKey.isAcceptable()) {
                            ServerSocketChannel readyChannel = (ServerSocketChannel) readyKey.channel();
                            System.out.println("可接受连接的channel Id:" + readyChannel.hashCode() + readyKey.attachment());
                            SocketChannel socketChannel1 = (SocketChannel) readyChannel.accept().configureBlocking(false);
                            System.out.println("接受连接后返回的channel Id" + socketChannel1.hashCode());
                            socketChannel1.register(selector, (SelectionKey.OP_READ | SelectionKey.OP_WRITE)).attach(name);
                            name++;
                        }
    
                        if (readyKey.isWritable()) {
                            SocketChannel readyChannel = (SocketChannel) readyKey.channel();
                            ByteBuffer buffer = ByteBuffer.allocate(512);
                            buffer.put(("to " + readyKey.attachment() + " " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "
    ")
                                    .getBytes());
                            buffer.flip();
                            readyChannel.write(buffer);
                        }
    
                        if (readyKey.isReadable()) {
                            SocketChannel readyChannel = (SocketChannel) readyKey.channel();
                            ByteBuffer buffer = ByteBuffer.allocate(512);
                            readyChannel.read(buffer);
                            System.out.println(readyKey.attachment() + " " + getString(buffer));
                        }
                    }
                }
                Thread.sleep(1000);
            }
        }
    
        /**
         * ByteBuffer 转换 String
         * 
         * @param buffer
         * @return
         */
        public static String getString(ByteBuffer buffer) {
            String string = "";
            try {
                for (int i = 0; i < buffer.position(); i++) {
                    string += (char) buffer.get(i);
                }
                return string;
            } catch (Exception ex) {
                ex.printStackTrace();
                return "";
            }
        }
    }

    此服务器有一个监听通道,时刻监听是否有客户端连接;如果有,则在accept()的时候,返回一个新通道,作为一个连接!

  • 相关阅读:
    firewall
    mtu测试
    bps和pps
    PC上装VM上装虚拟机
    jira添加工作流
    【Linux系列】Centos 7安装 PHP(四)
    【Linux系列】Centos 7安装 Nginx(三)
    【Linux系列】配置Centos 7的软件源(二)
    【Linux系列】Centos 7安装以及网络配置(一)
    Python3获取豆瓣图书标签的前20本热门书籍(一)
  • 原文地址:https://www.cnblogs.com/tengpan-cn/p/6529628.html
Copyright © 2011-2022 走看看