美文网首页
JavaNIO-通道09 ServerSocketChannel

JavaNIO-通道09 ServerSocketChannel

作者: 贪睡的企鹅 | 来源:发表于2019-07-25 20:29 被阅读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();
            }
        }    
    
    • supportedOptions() 返回通道支持的Socket
    • getOption() 返回指定Socket Option的值
    • setOption() 设置某个选项的值
    @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();
        }
    

    相关文章

      网友评论

          本文标题:JavaNIO-通道09 ServerSocketChannel

          本文链接:https://www.haomeiwen.com/subject/ummkrctx.html