JavaNIO-通道09 ServerSocketChannel

2019-07-25  本文已影响0人  贪睡的企鹅

ServerSocketChannel

用来表示服务端Socket通道,由于是SelectableChannel子类,支持非阻塞和选择器。

常用API

isBlocking :判断当前通道是否是阻塞IO模式

    @Test
    public void test_isBlocking() throws Exception {
        /** 实例化一个选择器对象 **/
        Selector selector = Selector.open();
        /** 创建服务器套接字通道 ServerSocketChannel **/
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        /** 绑定监听 InetSocketAddress **/
        serverSocketChannel.bind(new InetSocketAddress("localhost", 8888), 10);
        /** 查看当前通道阻塞状态 **/
        System.out.println(serverSocketChannel.isBlocking());
        /**  使用register函数将通道注册到选择器之前需要设置为非阻塞的通道 **/
        serverSocketChannel.configureBlocking(false);
        /** 查看当前通道阻塞状态 **/
        System.out.println(serverSocketChannel.isBlocking());

    }

keyFor

返回通道在向给定选择器Selector注册的SelectionKey

@Test
    public void test_keyFor() throws Exception {
        /** 实例化一个选择器对象 **/
        Selector selector = Selector.open();
        /** 创建服务器套接字通道 ServerSocketChannel **/
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        /** 绑定监听 InetSocketAddress **/
        serverSocketChannel.bind(new InetSocketAddress("localhost", 8888), 10);
        /** 设置为非阻塞IO模型 **/
        serverSocketChannel.configureBlocking(false);
        /**  使用register函数将SelectableChannel类型的通道注册到选择器,并设置感兴趣事件 **/
        SelectionKey register = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        /** 返回通道在向给定选择器Selector注册的SelectionKey 。 **/
        System.out.println(serverSocketChannel.keyFor(selector).equals(register));
    }

isRegistered 判断当前通道是否被注册到选择器Selector

 @Test
    public void test_isRegistered() throws Exception {
        /** 实例化一个选择器对象 **/
        Selector selector = Selector.open();
        /** 创建服务器套接字通道 ServerSocketChannel **/
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        /** 绑定监听 InetSocketAddress **/
        serverSocketChannel.bind(new InetSocketAddress("localhost", 8888), 10);

        /** 设置为非阻塞IO模型 **/
        serverSocketChannel.configureBlocking(false);
        /** 判断当前通道是否由被注册到选择器中 **/
        System.out.println(serverSocketChannel.isRegistered());
        /** 使用register函数将SelectableChannel类型的通道注册到选择器,并设置SelectionKey **/
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        /** 判断当前通道是否由被注册到选择器中 **/
        System.out.println(serverSocketChannel.isRegistered());
    }

validOps 返回通道支持的事件集合

@Test
    public void test_register_validOps_server() throws Exception {
        /** 创建服务器套接字通道 ServerSocketChannel **/
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        /** 绑定监听 InetSocketAddress **/
        serverSocketChannel.bind(new InetSocketAddress("localhost", 8888), 10);

        /** 设置为非阻塞IO模型 **/
        serverSocketChannel.configureBlocking(true);

        /** 阻塞等待客户端连接请求 **/
        SocketChannel socketChannel = serverSocketChannel.accept();

        System.out.println(serverSocketChannel.validOps());
        System.out.println(socketChannel.validOps());

        boolean isInterestedInAccept = (serverSocketChannel.validOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT;
        boolean isInterestedInConnect = (serverSocketChannel.validOps() & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT;
        boolean isInterestedInRead = (serverSocketChannel.validOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ;
        boolean isInterestedInWrite = (serverSocketChannel.validOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE;
        System.out.println(isInterestedInAccept);
        System.out.println(isInterestedInConnect);
        System.out.println(isInterestedInRead);
        System.out.println(isInterestedInWrite);

        System.out.println();

        isInterestedInAccept = (socketChannel.validOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT;
        isInterestedInConnect = (socketChannel.validOps() & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT;
        isInterestedInRead = (socketChannel.validOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ;
        isInterestedInWrite = (socketChannel.validOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE;
        System.out.println(isInterestedInAccept);
        System.out.println(isInterestedInConnect);
        System.out.println(isInterestedInRead);
        System.out.println(isInterestedInWrite);
    }
    
@Test
    public void test_register_validOps_client() throws Exception {
        Socket socket = null;
        OutputStream outputStream = null;
        try {
            /**建立连接**/
            socket = new Socket("localhost", 8888);
            TimeUnit.SECONDS.sleep(1000);
            /**向服务端发送数据**/
            outputStream = socket.getOutputStream();
            outputStream.write("client hello1".getBytes());
        } catch (Exception e) {
            System.out.println("socket 连接失败");
            e.getMessage();
        } finally {
            /** 客户端关闭连接 **/
            socket.close();
            outputStream.close();
        }
    }    
@Test
    public void test_socket_option_server() throws Exception {
        /** 创建服务器套接字通道 ServerSocketChannel **/
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        /** 绑定监听 InetSocketAddress **/
        serverSocketChannel.bind(new InetSocketAddress("localhost", 8888), 10);

        /** 设置为阻塞IO模型 **/
        serverSocketChannel.configureBlocking(true);
        SocketChannel socketChannel = serverSocketChannel.accept();

        Set<SocketOption<?>> socketOptions1 = serverSocketChannel.supportedOptions();
        Set<SocketOption<?>> socketOptions2 = socketChannel.supportedOptions();

        Iterator<SocketOption<?>> iterator1 = socketOptions1.iterator();
        Iterator<SocketOption<?>> iterator2 = socketOptions2.iterator();

        while (iterator1.hasNext()) {
            SocketOption<?> next = iterator1.next();
            System.out.println(next.name() + "" + next.getClass().getName());
        }
        System.out.println();
        System.out.println();
        while (iterator2.hasNext()) {
            SocketOption<?> next = iterator2.next();
            System.out.println(next.name() + "" + next.getClass().getName());
        }
        System.out.println(serverSocketChannel.getOption(StandardSocketOptions.SO_RCVBUF));
        serverSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 5678);
    }

    @Test
    public void test_socket_option_client() throws Exception {
        Socket socket = null;
        OutputStream outputStream = null;
        try {
            /**建立连接**/
            socket = new Socket("localhost", 8888);
            TimeUnit.SECONDS.sleep(1000);
            /**向服务端发送数据**/
            outputStream = socket.getOutputStream();
            outputStream.write("client hello1".getBytes());
        } catch (Exception e) {
            System.out.println("socket 连接失败");
            e.getMessage();
        } finally {
            /** 客户端关闭连接 **/
            socket.close();
            outputStream.close();
        }
    }

getLocalAddress() 获取服务端绑定地址信息

@Test
    public void test_localAddress_server() throws Exception {
        /** 创建服务器套接字通道 ServerSocketChannel **/
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        /** 绑定监听 InetSocketAddress **/
        serverSocketChannel.bind(new InetSocketAddress("localhost", 8888), 10);

        InetSocketAddress localAddress = (InetSocketAddress) serverSocketChannel.getLocalAddress();
        System.out.println(localAddress.getHostString());
        System.out.println(localAddress.getHostName());
        System.out.println(localAddress.getPort());
        serverSocketChannel.close();
    }

provider 返回通道的创建程序

@Test
    public void test_selectorProvider_server() throws Exception {
        SelectorProvider provider = SelectorProvider.provider();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        System.out.println(serverSocketChannel.provider());
        System.out.println(provider);
        provider.openSelector();
    }
上一篇 下一篇

猜你喜欢

热点阅读