NIO+线程池

直接上代码,不多说,里面有详细解释

class run implements Runnable{
    private Selector selector;
    SocketChannel socketChannel;

    public run(Selector selector, SocketChannel socketChannel) {
        this.selector = selector;
        this.socketChannel = socketChannel;
    }

    @Override
    public void run() {
        try {
            socketChannel.configureBlocking(false);
            socketChannel.register(selector,SelectionKey.OP_READ);
            while (selector.select()>0){
                System.out.println("有关注的事件发生......");
                Iterator iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()){
                    SelectionKey key = iterator.next();
                    if (key.isReadable()){
                        System.out.println("有可读事件发生");
                        //创建buffer实例,
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        buffer.clear();
                        int count = 0;
                        StringBuilder s = new StringBuilder();
                        //使用缓冲区将客户端发送的数据提取完毕。
                        while ((count = socketChannel.read(buffer))>0){
                            socketChannel.read(buffer);
                            System.out.println("循环接收");
                            buffer.flip();
                            byte[] bytes = new byte[buffer.remaining()];
                            buffer.get(bytes);
                            String msg = new String(bytes);
                            s.append(msg);
                            buffer.clear();
                            buffer.put(msg.getBytes());
                            buffer.flip();
                            socketChannel.write(buffer);
                            buffer.clear();
                        }
                        System.out.println(s.toString());
                        if (count<0){
                            socketChannel.close();
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class NIOServer1 {
    public static void main(String[] args) throws IOException {
        //1、创建ServerSocketChannel.open();实例
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //绑定端口
        serverSocketChannel.bind(new InetSocketAddress(5555));
        System.out.println("服务端启动");
        // 注册选择器
        Selector selector = Selector.open();
        //设置非阻塞
        serverSocketChannel.configureBlocking(false);
        //将其注册到选择器上
        //让选择器帮忙监听事件,有事件就返回,没有事件就不返回
        serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        while (selector.select() > 0){
            System.out.println("有关注的事件发生");
            //这是关注的事件集合
            Iterator iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                iterator.remove();
                if (key.isAcceptable()){
                    System.out.println("有可接收的事件发生");
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    SocketChannel socketChannel = channel.accept();
                    //多线程操作
                    executorService.execute(new run(Selector.open(),socketChannel));
                }
            }
        }
    }
}

客户端
和上一篇一样没有区别

public class NIOCilent {
    public static void main(String[] args) throws IOException {
//        创建实例SocketChannel.open();
        SocketChannel socketChannel = SocketChannel.open();

//        将SocketChannel实例设置为非阻塞
        socketChannel.configureBlocking(false);
//        创建selector实例
        Selector selector = Selector.open();

//        连接服务器
        if (!socketChannel.connect(new InetSocketAddress("127.0.0.1",5555))){
            System.out.println("连接为完成,注册到选择器当中");
            //        将Selector注册到选择器里面,并关注OP_CONNECT事件
            socketChannel.register(selector,SelectionKey.OP_CONNECT);
//            监听感兴趣的事件是否完成
            selector.select();

            Iterator iterator = selector.selectedKeys().iterator();

            while (iterator.hasNext()){
                System.out.println(">>>>"+selector.selectedKeys().size());
                SelectionKey key = iterator.next();
                iterator.remove();

                if (key.isValid()&&key.isConnectable()){
                    System.out.println("可连接事件完成");
                    SocketChannel channel = (SocketChannel) key.channel();

                    if (channel.isConnectionPending())
                        channel.finishConnect();
                    System.out.println("客户端连接成功");
                    channel.configureBlocking(false);

                    channel.register(selector,SelectionKey.OP_READ);
                }
            }
        }
//        连接完成进行读写操作
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.println("请输入:");
            String msg = scanner.nextLine();
            if ("exit".equals(msg)){
                break;
            }
//          向缓存写数据
            byteBuffer.put(msg.getBytes());
            byteBuffer.flip();
//        发送数据
            socketChannel.write(byteBuffer);
//        缓存清空
            byteBuffer.clear();
//        监听读事件,没有则阻塞
            selector.select();
            socketChannel.read(byteBuffer);
//            读写模式切换
            byteBuffer.flip();
//            通过缓冲区有效元素大小确定数组大小
            byte[] bytes1 = new byte[byteBuffer.remaining()];
//            从缓冲区读数据
            byteBuffer.get(bytes1);
            String msg1 = new String(bytes1);
            System.out.println("[recv]:"+msg1);
            byteBuffer.clear();

        }

        System.out.println("客户端关闭");
        selector.close();
        socketChannel.close();
    }
}

你可能感兴趣的:(网络编程)