zoukankan      html  css  js  c++  java
  • NIO简单客户端与服务端实现代码

    public class TestNonBlockingNIO {
    
        //客户端
        @Test
        public void client() throws IOException{
            // 1. 获取通道
            SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
            // 2. 切换非阻塞模式
            sChannel.configureBlocking(false);
            // 3. 分配指定大小的缓冲区
            ByteBuffer buf = ByteBuffer.allocate(1024);
            // 4. 发送数据给服务端
            String str = "hello";
            buf.put((new Date().toString() + "
    " + str).getBytes());
            buf.flip();
            sChannel.write(buf);
            sChannel.shutdownOutput();
            // 5. 关闭通道
            sChannel.close();
        }
    
        //服务端
        @Test
        public void server() throws IOException{
            //1. 获取通道
            ServerSocketChannel ssChannel = ServerSocketChannel.open();
            //2. 切换非阻塞模式
            ssChannel.configureBlocking(false);
            //3. 绑定连接
            ssChannel.bind(new InetSocketAddress(9898));
            //4. 获取选择器
            Selector selector = Selector.open();
            //5. 将通道注册到选择器上, 并且指定“监听接收事件”
            ssChannel.register(selector, SelectionKey.OP_ACCEPT);
            //6. 轮询式的获取选择器上已经“准备就绪”的事件
            while(selector.select() > 0){
                //7. 获取当前选择器中所有注册的“选择键(已就绪的监听事件)”
                Iterator<SelectionKey> it = selector.selectedKeys().iterator();
                while(it.hasNext()){
                    //8. 获取准备“就绪”的是事件
                    SelectionKey sk = it.next();
                    //9. 判断具体是什么事件准备就绪
                    if(sk.isAcceptable()){
                        ServerSocketChannel ss = (ServerSocketChannel) sk.channel();
                        //10. 若“接收就绪”,获取客户端连接
                        SocketChannel sChannel = ss.accept();
                        //11. 切换非阻塞模式
                        sChannel.configureBlocking(false);
                        //12. 将该通道注册到选择器上
                        sChannel.register(selector, SelectionKey.OP_READ);
                    }else if(sk.isReadable()){
                        //13. 获取当前选择器上“读就绪”状态的通道
                        SocketChannel sChannel = (SocketChannel) sk.channel();
                        //14. 读取数据
                        ByteBuffer buf = ByteBuffer.allocate(1024);
                        int len = 0;
                        while((len = sChannel.read(buf)) > 0 ){
                            buf.flip();
                            System.out.println(new String(buf.array(), 0, len));
                            buf.clear();
                        }
                        if(len == -1){
                            System.out.println("断开");
                            sChannel.close();
                        }
                    }
                    //15. 取消选择键 SelectionKey
                    it.remove();
                }
            }
        }
    }
  • 相关阅读:
    WPF DelegateCommand 出现Specified cast is not valid
    WPF DelegateCommand 出现Specified cast is not valid
    WPF DelegateCommand 出现Specified cast is not valid
    win10 sdk 是否向下兼容
    win10 sdk 是否向下兼容
    win10 sdk 是否向下兼容
    PHP extract() 函数
    PHP end() 函数
    PHP each() 函数
    PHP current() 函数
  • 原文地址:https://www.cnblogs.com/vegeta-xiao/p/12612561.html
Copyright © 2011-2022 走看看