Netty学习——实战篇1 BIO、NIO入门demo 备注

 1 BIO 实战代码 

@Slf4j
public class BIOServer {
    public static void main(String[] args) throws IOException {
        //1 创建线程池
        ExecutorService threadPool = Executors.newCachedThreadPool();
        //2 创建ServerSocket
        ServerSocket serverSocket = new ServerSocket(8000);

        log.info("服务器已启动成功");
        //3 监听,等待客户端连接
        while(true){
            log.info("线程id:{}",Thread.currentThread().getId());
            log.info("等待连接...");
            //4 客户端连接后,创建一个线程,与客户端通信
            final Socket socket = serverSocket.accept();
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    handler(socket);
                }
            });
        }

    }

    //编写一个handler方法,与客户端通信
    public static  void handler(Socket socket){
        try {
            log.info("线程id:{}",Thread.currentThread().getId());
            //创建一个byte[]数组
            byte[] bytes = new byte[1023];
            //通过socket获取输入流
            InputStream inputStream = socket.getInputStream();
            //循环读取客户端发送的消息
            while(true){
                int read = inputStream.read(bytes);
                if(read != -1){
                    System.out.println(new String(bytes,0,read));
                }else{
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                log.info("关闭与客户端的连接");
                socket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

        运行结果

8621025cda1d47839eed300130b406cd.png

2 NIO实战

2.1 Buffer实战

@Slf4j
public class BasicBuffer {
    public static void main(String[] args) {
        //1 创建一个Buffer
        IntBuffer buffer = IntBuffer.allocate(10);
        //2 往Buffer存储数据
        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put(i * 2);
        }
        //3 Buffer读写切换
        buffer.flip();
        //4 Buffer 读数据
        while(buffer.hasRemaining()){
            log.info("{}",buffer.get());
        }
    }
}

 

2.2 FileChannel实战

        使用NIO的FileChannel和ByteBuffer,把一段文字写入到指定的文件中。

//把文字写入到指定文件中
public class FileChannelWrite{
    public static void main(String[] args) throws IOException {
        //1 指定文字
        String str = "hello,孔乙己";
        //2 创建一个输出流
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\develop\\java-base\\test\\test01.txt");
        //3 通过输出流创建FileChannel
        java.nio.channels.FileChannel fileChannel = fileOutputStream.getChannel();
        //4 创建一个缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        //5 把文字放入缓冲区buffer中
        buffer.put(str.getBytes());
        //6 对buffer进行翻转
        buffer.flip();
        //7 把buffer的数据写入到FileChannel
        fileChannel.write(buffer);
        //8 关闭流
        fileOutputStream.close();
    }
}

 

        使用NIO的FileChannel和Bytebuffer,读取指定文件中的内容,并打印到控制台

@Slf4j
public class FileChannelRead {
    public static void main(String[] args) throws IOException {
        //1 创建输入流
        File file = new File("D:\\develop\\java-base\\test\\test01.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        //2 通过输入流创建FileChannel
        FileChannel fileChannel = fileInputStream.getChannel();
        //3 创建缓冲区
        ByteBuffer buffer = ByteBuffer.allocate((int) file.length());
        //4 把通道的数据读取到缓冲区
        fileChannel.read(buffer);
        //5 把bytebuffer 转成 string
        log.info("文件的内容是: {}",new String(buffer.array()));
        //6 关闭输入流
        fileInputStream.close();
    }
}

 

        使用一个Buffer,FileChannel和read/write方法,完成文件的拷贝 .

public class FileChannelCopy {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream("D:\\develop\\java-base\\test\\source.txt");
        FileChannel inputChannel = fileInputStream.getChannel();

        FileOutputStream fileOutputStream = new FileOutputStream("D:\\develop\\java-base\\test\\target.txt");
        FileChannel outChannel = fileOutputStream.getChannel();

        ByteBuffer buffer = ByteBuffer.allocate(1024);

        while (true){
            buffer.clear();
            int read = inputChannel.read(buffer);
            if(read == -1){
                break;
            }
            buffer.flip();
            outChannel.write(buffer);
        }
        fileInputStream.close();
        fileOutputStream.close();

    }
}

        使用transferFrom方法拷贝文件 

public class FileChannelCopy01 {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream("D:\\develop\\java-base\\test\\source.png");
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\develop\\java-base\\test\\dest.png");

        FileChannel inChannel = fileInputStream.getChannel();
        FileChannel outChannel = fileOutputStream.getChannel();

        outChannel.transferFrom(inChannel,0,inChannel.size());

        fileInputStream.close();
        fileOutputStream.close();
    }
}

2.3 MappedByteBufer

         MappedByteBufer 可以让文件直接在内存(堆外内存)修改,操作系统不需要再拷贝一次

//原来的内容是:hello,孔乙己
//修改后的内容是:HelLo,孔乙己
public class MappedByteBuffer {
    public static void main(String[] args) throws IOException {
        RandomAccessFile randomAccessFile = new RandomAccessFile("D:\\develop\\java-base\\test\\test01.txt", "rw");
        FileChannel channel = randomAccessFile.getChannel();
        java.nio.MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
        map.put(0,(byte) 'H');
        map.put(3,(byte) 'L');
        randomAccessFile.close();
    }
}

2.4 ServerSocketChannel和SocketChannel

@Slf4j
public class ServerSocketChannelAndSocketChannel {
    public static void main(String[] args) throws IOException {
        //1 使用ServerSocketChannel和SocketChannel 网络
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        InetSocketAddress address = new InetSocketAddress(8000);

        //2 绑定端口到socket,并启动
        serverSocketChannel.socket().bind(address);
        //3 创建 ByteBuffer数组
        ByteBuffer[] buffers = new ByteBuffer[2];
        buffers[0] = ByteBuffer.allocate(5);
        buffers[1] = ByteBuffer.allocate(3);
        //4 等待客户端连接
        SocketChannel socketChannel = serverSocketChannel.accept();
        int messageLength = 8;//假定从客户端接收到8个字节
        //5 循环读取
        while(true){
            int byteRead = 0;
            while(byteRead < messageLength){
                long read = socketChannel.read(buffers);
                byteRead += read;
                log.info("byteRead = ,{}",byteRead);
                //使用流打印,查看当前的这个buffer的position和limit
                Arrays.asList(buffers).stream().
                        map(buffer -> "position = " +
                                buffer.position() +
                                ",limit = " + buffer.limit()
                        ).forEach(System.out::println);
            }
            // 6 将所有的buffer进行翻转
            Arrays.asList(buffers).forEach(buffer -> buffer.flip());
            // 将数据读取到客户端
            long byteWrite = 0;
            while(byteWrite < messageLength){
                long l = socketChannel.write(buffers);
                byteWrite += l;
            }
            //将所有的buffer进行翻转
            Arrays.asList(buffers).forEach(buffer ->{buffer.clear();
            });
            log.info("byteRead = ,{},byteWrite = {},messageLength = {}",byteRead,byteWrite,messageLength);
        }
        
    }
}

2.5 使用NIO开发服务端和客户端

        NIOServer.java 

 

@Slf4j
public class NIOServer {
    public static void main(String[] args) throws Exception{
        //1 创建ServerSocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //2 创建Selector对象
        Selector selector = Selector.open();
        //3 绑定端口 8000,在服务器监听
        serverSocketChannel.socket().bind(new InetSocketAddress(8000));
        //4 ServerSocketChannel设置为非阻塞
        serverSocketChannel.configureBlocking(false);
        //5 把ServerSocketChannel的OP_ACCEPT注册到selector
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        log.info("ServerSocketChannel已注册到Selector上");
        // 6 循环,等待客户端连接
        while(true){
            //7 等待一秒,如果没有事件发生,就返回
            if(selector.select(1000) == 0){
                log.info("等待1秒,没有客户端连接");
                continue;
            }
            //8 如果有事件发生,就获取selectedKyes,返回关注事件的集合
            Set<SelectionKey> selectededKeys = selector.selectedKeys();
            Iterator<SelectionKey> keyIterator = selectededKeys.iterator();
            //9 遍历selectedKeys集合,获取事件类型
            while(keyIterator.hasNext()){

                SelectionKey key = keyIterator.next();
                if(key.isAcceptable()){
                    log.info("客户端连接成功");
                    //10_1 如果是OP_ACCEPT事件,证明有新的客户端连接,为该客户端创建一个SocketChannel
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    //10_1_1 将SocketChannel注册到selector上,事件类型是OP_READ,并绑定一个缓冲区
                    socketChannel.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                }
                if(key.isReadable()){
                    //10_2  如果是OP_READ事件,通过selectedKey 反向获取 SocketChannel
                    SocketChannel channel =(SocketChannel) key.channel();
                    //10_2_1  获取该channel绑定的buffer,并读取
                    ByteBuffer buffer = (ByteBuffer)key.attachment();
                    channel.read(buffer);
                    log.info("从客户端读取的数据是: {}",new String(buffer.array()));
                }
                //11 移除selectedKey,防止重复操作
                keyIterator.remove();

            }

        }

    }
}

        NIOClient.java

 

@Slf4j
public class NIOClient {
    public static void main(String[] args) throws Exception {
        //1 创建SocketChannel
        SocketChannel socketChannel = SocketChannel.open();
        //2 设置非阻塞模式
        socketChannel.configureBlocking(false);
        //3  提供服务器的ip和端口
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8000);
        //4 连接服务器
        if(!socketChannel.connect(address)){
            // 4_1 连接失败
            while(!socketChannel.finishConnect()){
                log.info("连接需要时间,此时客户端不会阻塞,可以做其他工作。。。");
            }
        }
        //4_2 连接成功,发送数据
        String str = "hello ,孔乙己";
        ByteBuffer buffer = ByteBuffer.wrap(str.getBytes());
        socketChannel.write(buffer);
        System.in.read();
    }
}

        运行结果:

cac6746784044121871985398c1944f7.png

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/536904.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高清无水印短视频素材去哪找?今天讲五个素材网站,记得收藏

在视频剪辑的世界里&#xff0c;我就像是那个经常带着一副老花镜在宝藏地图上寻宝的老海盗。每次寻宝之旅&#xff0c;我都能从九才素材网这个家门口的宝藏开始&#xff0c;然后驾驶我的老旧剪辑船&#xff0c;航向国际的深蓝大海&#xff0c;寻找那些只属于知情者的秘密宝藏。…

【C++进阶】C++异常详解

C异常 一&#xff0c;传统处理错误方式二&#xff0c;C处理的方式三&#xff0c;异常的概念四&#xff0c;异常的使用4.1 异常和捕获的匹配原则4.2 函数调用链中异常栈展开匹配原则4.3 异常的重新抛出&#xff08;异常安全问题&#xff09;4.4 RAII思想在异常中的作用 五&#…

使用Java+Maven+TestNG进行自动化测试

写作背景&#xff1a;有点Java基础的功能测试人员&#xff08;点点点工程师&#xff09;&#xff0c;所在项目有"去QE"的趋势&#xff0c;所以自己要多点亮其他技能&#xff0c;让路子走宽点。 简单说一下去QE&#xff1a;项目测试不再有专职的测试工程师来做&#x…

计算机网络——40各个层次的安全性

各个层次的安全性 安全电子邮件 Alice需要发送机密的报文m给Bob Alice 产生随机的对称秘钥&#xff0c; K s K_s Ks​使用 K s K_s Ks​对报文进行加密&#xff08;为了效率&#xff09;对 K s K_s Ks​使用Bob的公钥进行加密发送 K s ( m ) K_s(m) Ks​(m)和 K B ( K S ) K…

小程序/app/H5多端圈子社区论坛系统交友/社交/陌生人社交即时聊天私域话题社区论坛 行业圈子小程序 微信社区小程序圈子论坛社区小程序

项目介绍 这是一个社区论坛类小程序项目源码&#xff0c;可以实现用户发送自定义图文内容&#xff0c;点赞&#xff0c;评论&#xff0c;回复&#xff0c;记录评论过的帖子&#xff0c;记录发表过的帖子&#xff0c;左滑删除&#xff0c;在线实时接收消息&#xff0c;离线接收…

MySQL高级篇(索引概述、优缺点、结构 B+Tree)

目录 1、索引概述 2、索引优缺点 3、索引的结构 1、索引概述 介绍&#xff1a;索引&#xff08;index&#xff09;是帮助MySQL 高效获取数据 的 数据结构&#xff08;有序&#xff09;。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数…

分布式系统:缓存与数据库一致性问题

前言 缓存设计是应用系统设计中重要的一环&#xff0c;是通过空间换取时间的一种策略&#xff0c;达到高性能访问数据的目的&#xff1b;但是缓存的数据并不是时刻存在内存中&#xff0c;当数据发生变化时&#xff0c;如何与数据库中的数据保持一致&#xff0c;以满足业务系统…

java实现TCP交互

服务器端 import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.PriorityQueue; import java.util.Scanner;public class TCP_Serv…

(文章复现)考虑网络动态重构的分布式电源选址定容优化方法

参考文献&#xff1a; [1]朱俊澎,顾伟,张韩旦,等.考虑网络动态重构的分布式电源选址定容优化方法[J].电力系统自动化,2018,42(05):111-119. 1.摘要 以投资周期经济收益最高为目标&#xff0c;基于二阶锥规划提出了一种考虑网络动态重构的分布式电源选址定容优化方法。首先&am…

OpenStack (T)部署trove

环境&#xff1a;Openstack&#xff08;T&#xff09; CentOS Linux release 7.9.2009 (Core) 正文&#xff1a; 1.控制节点安装trove软件包 # yum install openstack-trove-guestagent openstack-trove python-troveclient openstack-trove-ui –y2.创建数据库&#xff0c…

动态代理 --java学习笔记

什么是动态代理&#xff1f; 当一个类的很多方法都存在重复冗杂的部分&#xff0c;就可以使用代理来处理那些重复部分的任务&#xff0c;到了各自的实现部分再丢回给原方法处理&#xff0c;同时也可以提高方法的扩展性&#xff0c;而动态则是指在运行时动态地创建代理对象&…

【高德地图笔试题汇总】2024-04-11-高德地图春招笔试题-三语言题解(CPP/Python/Java)

&#x1f36d; 大家好这里是KK爱Coding &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新高德地图近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&…

【感谢】心怀感恩,共赴知识之旅——致每一位陪伴我突破百万总访问量的您

小伙伴朋友们&#xff1a; 此刻&#xff0c;我怀着无比激动与深深感激的心情&#xff0c;写下这篇特别的博文。今天&#xff0c;我的CSDN总访问量成功突破了百万大关&#xff0c;这不仅是一个数字的跨越&#xff0c;更是你们对我的支持、信任与鼓励的有力见证。在此&#xff0…

前端Vue自定义勾选协议组件的开发与应用

摘要&#xff1a; 随着前端技术的不断发展&#xff0c;用户体验成为了软件开发中的关键要素。在登录、注册等场景中&#xff0c;勾选协议是常见的需求。本文旨在介绍一款基于 Vue.js 的自定义勾选协议组件的开发与应用&#xff0c;该组件适用于多种场景&#xff0c;并且具备良…

图形学基础:二维三维刚体的移动、缩放和旋转矩阵

一、二维 1.1 缩放矩阵 x&#xff0c;y分别表示在x轴&#xff0c;y轴缩放的倍数 示例&#xff1a; 点(2,1)在x&#xff0c;y轴上分别缩放x倍&#xff0c;y倍 1.2 平移矩阵 x&#xff0c;y分表表示在x轴&#xff0c;y轴上移动的距离 示例&#xff1a;点&#xff08;2,1&#xf…

C语言——指针的高级引用

目录 1.概述 2.虚拟内存空间 2.1存储期限 2.2栈区管理 2.3堆区域的使用 3.动态内存分配和释放&#xff08;重点&#xff09; 3.1通用指针类型void 3.2内存分配malloc函数 3.2.1 malloc函数&#xff08;memory allocation&#xff09;&#xff08;注意len*size&#xff…

工智能图像降噪软件 ON1 NoNoise AI 2024 for Mac激活版

ON1 NoNoise AI 2024 for Mac是一款专为Mac用户设计的先进人工智能图像降噪软件。其核心功能在于能够利用机器学习技术&#xff0c;快速并智能地消除图像中的噪点&#xff0c;无论是亮度噪点还是颜色噪点&#xff0c;都能得到显著的改善。 软件下载&#xff1a;ON1 NoNoise AI …

【高项】信息化发展

目录 1.1 信息与信息化 1.1.1 信息 1.信息的定义 2.信息的特征与质量 1.1.2 信息系统 1.信息系统及其特性 2.信息系统生命周期 1.1.3 信息化 1.信息化内涵 2.信息化体系&#xff08;口诀&#xff1a;上应下技左人右规&#xff0c;中资网&#xff09; 1.2 现代化基础…

Vue笔记 2

数据代理 数据代理&#xff1a;通过一个对象代理对另一个对象中属性的操作&#xff08;读/写&#xff09; let obj{x:100} let obj2{y:200} Object.defineProperty(obj2,x,{get(){return obj.x},set(value){obj.x value} })Vue中的数据代理 Vue中的数据代理&#xff1a; 通…

【go从入门到精通】作用域,包详解

作者简介&#xff1a; 高科&#xff0c;先后在 IBM PlatformComputing从事网格计算&#xff0c;淘米网&#xff0c;网易从事游戏服务器开发&#xff0c;拥有丰富的C&#xff0c;go等语言开发经验&#xff0c;mysql&#xff0c;mongo&#xff0c;redis等数据库&#xff0c;设计模…