SocketChannel和Selector

非阻塞模式与选择器搭配会工作的更好,通过将一或多个SocketChannel注册到Selector,可以询问选择器哪个通道已经准备好了读取,写入等

 

上面已经分别介绍过SocketChannel和Selector 但是非阻塞模式与选择器搭配工作的代码没有整合。

如下就是非阻塞模式使用选择器的代码:

 

 private static final int TIMEOUT = 3000;
    private static final int BUF_SIZE=1024;
    private static final int PORT = 9999;

    @Test
    public void test1()  throws IOException, InterruptedException {
        test("I'm 1st information from client");
    }

    @Test
    public void test3()  throws IOException, InterruptedException {
        test("I'm 2st information from client");
    }

    public void test(String info) throws IOException, InterruptedException {
        SocketChannel socketChannel = SocketChannel.open();
        //设置为NIO
        socketChannel.configureBlocking(false);
        socketChannel.connect(new InetSocketAddress("localhost", PORT));
        ByteBuffer buf = ByteBuffer.allocate(BUF_SIZE);
        if(socketChannel.finishConnect())
        {
            while(true)
            {
                TimeUnit.SECONDS.sleep(1);
                buf.clear();
                buf.put(info.getBytes());
                buf.flip();
                while(buf.hasRemaining()){
                    socketChannel.write(buf);
                }
            }
        }
    }



    @Test
    public void test2() throws IOException {
        Selector selector = Selector.open();
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress(PORT));
        ssc.configureBlocking(false);
//        int interestSet = SelectionKey.OP_READ & SelectionKey.OP_WRITE  & SelectionKey.OP_ACCEPT;
        ssc.register(selector,SelectionKey.OP_ACCEPT );

        while(true){
            if(selector.select(TIMEOUT) == 0){
                System.out.println("==");
                continue;
            }
            Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
            while(iter.hasNext()){
                SelectionKey key = iter.next();
                if(key.isAcceptable()){
                    handleAccept(key);
                }
                if(key.isReadable()){
                    handleRead(key);
                }
                if(key.isWritable() && key.isValid()){
                    handleWrite(key);
                }
                if(key.isConnectable()){
                    System.out.println("isConnectable = true");
                }
                iter.remove();
            }
        }
    }

    public static void handleWrite(SelectionKey key) throws IOException{
        ByteBuffer buf = (ByteBuffer)key.attachment();
        buf.flip();
        SocketChannel sc = (SocketChannel) key.channel();
        while(buf.hasRemaining()){
            sc.write(buf);
        }
        buf.compact();
    }

    public static void handleAccept(SelectionKey key) throws IOException{
        ServerSocketChannel ssChannel = (ServerSocketChannel)key.channel();
        SocketChannel sc = ssChannel.accept();
        sc.configureBlocking(false);
        sc.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocate(BUF_SIZE));
    }
    public static void handleRead(SelectionKey key) throws IOException{
        SocketChannel sc = (SocketChannel)key.channel();
        ByteBuffer buf = (ByteBuffer)key.attachment();
        long bytesRead = sc.read(buf);
        while(bytesRead>0){
            buf.flip();
            while(buf.hasRemaining()){
                System.out.print((char)buf.get());
            }
            System.out.println();
            buf.clear();
            bytesRead = sc.read(buf);
        }
        if(bytesRead == -1){
            sc.close();
        }
    }
posted @ 2020-01-20 10:30  reload  阅读(813)  评论(0编辑  收藏  举报