NIO:NIO综合通道测试

NIO通道客户端:
实现步骤

  1. 打开通道
  2. 指定IP和端口号
  3. 写出数据
  4. 读取服务器写回的数据
  5. 释放资源
public static void main(String[] args) throws Exception {
        //打开通道
        SocketChannel open = SocketChannel.open ();
        //指定IP和端口号
        open.connect (new InetSocketAddress ("192.168.10.52", 4399));
        ByteBuffer buffer = ByteBuffer.wrap ("你艾希我奶妈".getBytes ());
        open.write (buffer);
        open.shutdownOutput ();//告诉服务器数据已经把数据发送完毕
        //读取服务器回送的消息
        ByteBuffer byteBuffer2 = ByteBuffer.allocate(1024);
        buffer.flip ();
        int len;
        while((len = open.read(byteBuffer2)) != -1){
            System.out.println("客户端接收回写数据");
            String s = new String (byteBuffer2.array (), 0, len);
            System.out.println (s);
            byteBuffer2.clear();
        }
        open.close();
    }

NIO通道服务端:
实现步骤

  1. 打开一个服务端通道(open)

  2. 绑定对应的端口号

  3. 通道默认是阻塞的,需要设置为非阻塞

  4. 打开一个选择器(门卫大爷)

  5. 将选择器绑定服务端通道,并监视服务端是否准备好

  6. 如果有客户端来连接了,大爷会遍历所有的服务端通道,谁准备好了,就让谁来连接
    连接后,在服务端通道内部,再创建一个客户端延伸通道

  7. 如果客户端把数据传递过来了,大爷会遍历所有的延伸通道,谁准备好了,谁去接收数据

public static void main(String[] args) throws IOException {

        //1.打开服务器通道,绑定通道端口
        ServerSocketChannel open = ServerSocketChannel.open ();
        ServerSocketChannel bind = open.bind (new InetSocketAddress (4399));


        //2.设置f服务通道为非堵塞,默认为堵塞
        open.configureBlocking (false);
       // SocketChannel accept1 = open.accept ();

        //3.打开选择器 Selector
        Selector selector = Selector.open ();

        //4.绑定选择器和服务通道状态
        open.register (selector, SelectionKey.OP_ACCEPT);

        while (true){
            //6.连接的用户数,表示此时有多少个客户端来连接
            int count = selector.select ();

            if(count!=0){
                System.out.println ("有客户端来连接");
                //7.用集合存储所有用户的通道的状态,遍历所有的服务端通道状态信息
                Set<SelectionKey> selectionKeys = selector.selectedKeys ();
                Iterator<SelectionKey> iterator = selectionKeys.iterator ();
                while (iterator.hasNext ()){
                    //8.获取到当前通道的状态
                    SelectionKey next = iterator.next ();

                    if(next.isAcceptable ()){
                        //9.获取到一个就绪的通道,强行转换为ServerSocketChannel
                        ServerSocketChannel channel =(ServerSocketChannel) next.channel ();

                        //10.在服务端通道内部,再创建一个客户端通道,相当于是客户端通道的延伸,接受客户端发送的信息
                        SocketChannel accept = channel.accept ();

                        //将客户端通道设置为非堵塞
                        accept.configureBlocking (false);

                        //4.绑定选择器和改变服务通道状态
                        accept.register(selector,SelectionKey.OP_READ);
                    }else if(next.isReadable ()){
                        //需要读取 客户端中的数据
                        SocketChannel channel =(SocketChannel) next.channel ();
                        ByteBuffer arr = ByteBuffer.allocate (1024);
                        byte[] array = arr.array ();
                        while (true){
                            int len=channel.read (arr);
                            if(len==-1){
                                //读取到数据的最后没有就返回-1,改变通道状态
                                channel.register(selector,SelectionKey.OP_WRITE);
                                break;
                            }else if(len==0){
                                break;
                            }else if(len>0){
                                System.out.println("服务端接收客户端发送数据");
                                String msg = new String (array, 0, len);
                                String ip = channel.getRemoteAddress ().toString ();
                                System.out.println (ip+""+msg);
                            }
                        }
                    }else if(next.isWritable ()){
                        SocketChannel channel =(SocketChannel) next.channel ();
                        ByteBuffer wrap = ByteBuffer.wrap ("宝塔镇河妖".getBytes ());
                        channel.write (wrap);
                        channel.close ();
                    }
                }
                iterator.remove ();
            }
        }
    }
上一篇:Leetcode 190. Reverse Bits(反转比特数)


下一篇:Android 生产者-消费者模型实现数据同步