详解Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

yizhihongxing

针对这个话题,我将分几个部分进行详细讲解。

1. 了解Java 网络IO编程

1.1 BIO

BIO即Blocking IO,同步阻塞IO,应用方面比较广泛,缺点是每个客户端连接时都需要创建一个线程,因此比较消耗系统资源,如果客户端连接数比较少,建议使用BIO。

1.2 NIO

NIO即Non-blocking IO,同步非阻塞IO,优点是可以支持多路复用,一个线程可以处理多个客户端连接,缺点是编程复杂,需要熟练掌握Selector、Channel、Buffer等概念。

1.3 AIO

AIO即Asynchronous IO,异步非阻塞IO,通常由操作系统来完成数据传输,Java 7后提供了NIO 2.0,支持异步IO,相较NIO来说,AIO更加简单易用。

2. 示例代码说明

下面我会通过两个具体的示例来说明BIO、NIO、AIO的使用。

2.1 BIO 示例

BIO使用中每个客户端连接时都需要创建一个线程,因此比较消耗系统资源。下面是一个BIO示例代码:

public class BIOServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("Server start at:8888");
        while(true){
            Socket socket = serverSocket.accept();
            Handler handler = new Handler(socket);
            new Thread(handler).start();
        }
    }

    static class Handler implements Runnable{
        Socket socket;
        public Handler(Socket socket) {
            this.socket = socket;
        }
        @Override
        public void run() {
            InputStream inputStream = null;
            try {
                inputStream = socket.getInputStream();
                byte[] bytes = new byte[1024];
                int len;
                StringBuilder sb = new StringBuilder();
                while ((len = inputStream.read(bytes)) != -1){
                    sb.append(new String(bytes,0,len,"UTF-8"));
                }
                System.out.println("Server receive message:" + sb);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if(inputStream != null){
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

2.2 NIO 示例

NIO使用中可以一个线程处理多个客户端连接,相较BIO来说,可以更加节省系统资源。下面是一个NIO示例代码:

public class NIOServer {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(8888));

        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            int readyChannels = selector.select();
            if (readyChannels == 0) continue;
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> keyIterator = selectionKeys.iterator();
            while (keyIterator.hasNext()) {
                SelectionKey key = keyIterator.next();
                if (key.isAcceptable()) {
                    ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
                    SocketChannel channel = serverChannel.accept();
                    channel.configureBlocking(false);
                    channel.register(selector, SelectionKey.OP_READ);
                    System.out.println("客户端连接成功,IP地址为:" + channel.getRemoteAddress());
                } else if (key.isReadable()) {
                    SocketChannel channel = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int read = channel.read(buffer);
                    if (read > 0) {
                        buffer.flip();
                        byte[] bytes = new byte[buffer.remaining()];
                        buffer.get(bytes);
                        String message = new String(bytes, "UTF-8");
                        System.out.println("Server receive message:" + message);
                    } else if (read < 0) {
                        key.cancel();
                        channel.close();
                    }
                }
                keyIterator.remove();
            }
        }
    }
}

2.3 AIO 示例

AIO使用中相较NIO来说更加简单易用,Java 7以后提供了NIO 2.0支持异步IO。下面是一个AIO示例代码:

public class AIOEchoServer {
    private AsynchronousServerSocketChannel serverSocketChannel;

    public AIOEchoServer(int port) throws Exception {
        serverSocketChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(port));
    }

    public void start() {
        serverSocketChannel.accept(this, new CompletionHandler<AsynchronousSocketChannel, AIOEchoServer>() {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            @Override
            public void completed(AsynchronousSocketChannel channel, AIOEchoServer attachment) {
                buffer.clear();
                baos.reset();
                try {
                    channel.read(buffer).get();
                    buffer.flip();
                    baos.write(buffer.array(), 0, buffer.remaining());
                    String message = new String(baos.toByteArray(), "UTF-8");
                    System.out.println("Server receive message:" + message);
                    buffer.clear();
                    channel.write(ByteBuffer.wrap(("Echo:" + message).getBytes("UTF-8"))).get();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void failed(Throwable exc, AIOEchoServer attachment) {
                exc.printStackTrace();
            }
        });
        System.out.println("Server start at:8888");
    }

    public static void main(String[] args) throws Exception {
        new AIOEchoServer(8888).start();
        Thread.sleep(100000);
    }
}

在这里,通过以上三个示例,可以很好地了解BIO、NIO、AIO这三种不同网络IO编程模型的使用方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码) - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • Java实现Excel导入导出数据库的方法示例

    下面是Java实现Excel导入导出数据库的方法示例的完整攻略: 一、Excel导入数据库: 首先,需要添加相关的依赖包,如以下示例代码所示: <!– poi组件 –> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi&…

    Java 2023年5月20日
    00
  • Java如何调用TSC打印机进行打印详解

    关于Java如何调用TSC打印机进行打印,一般可以通过以下步骤来实现: 1. 前置条件 确认TSC打印机已经按照相应的通信协议和驱动程序与计算机进行连接和配置 了解打印指令,并准备好需要打印的内容 2. 使用TSC指令打印 2.1 建立连接 在Java中使用TSC指令打印,需要借助于TSC封装好的指令集,具体步骤如下: 导入TSC指令集jar包 xml &l…

    Java 2023年5月26日
    00
  • javabean servlet jsp实现分页功能代码解析

    下面是关于“javabean servlet jsp实现分页功能代码解析”的完整攻略。 一、需求分析 在实现分页功能之前,我们需要对所需功能进行详细的需求分析。具体包括: 需要分页的数据源(如数据库中的表); 需要展示的列信息,以及每页展示的记录条数; 需要实现的分页功能,包括首页、上一页、下一页、尾页等操作。 二、实现思路 接下来,我们需要对分页功能的实现…

    Java 2023年6月15日
    00
  • java list,set,map,数组间的相互转换详解

    Java List, Set, Map, 数组间的相互转换详解 在Java中,我们通常会使用List、Set、Map、数组这几种数据结构。他们各自有自己的特点和用途。有时我们需要将它们之间相互进行转换,下面是转换的方法和示例说明。 1. List 和 数组的相互转换 List 转 数组 使用 List 的 toArray 方法可以将 List 转为数组,方法…

    Java 2023年5月26日
    00
  • uniApp常见面试题及答案(推荐!)

    一、uniApp常见面试题及答案(推荐!) 在这篇文章中,我们将回答一些与uniApp相关的常见面试问题,包括uniApp的优点、uniApp的适用范围、uniApp的限制以及uniApp与其他框架的比较等。 以下是一些常见的uniApp面试问题及其答案: 什么是uniApp? uniApp是一款基于Vue.js的跨平台开发框架,可以用于开发iOS、Andr…

    Java 2023年5月23日
    00
  • Spring Security权限管理实现接口动态权限控制

    以下是关于Spring Security权限管理实现接口动态权限控制的完整攻略: 1. 什么是接口动态权限控制 接口动态权限控制即根据用户的权限动态的对接口进行权限控制,这个过程可以分为两步:一是获取用户所拥有的权限,二是根据用户所拥有的权限动态的对接口进行控制。 2. Spring Security实现接口动态权限控制的步骤 以下是实现Spring Sec…

    Java 2023年6月3日
    00
  • GraalVM和Spring Native尝鲜一步步让Springboot启动飞起来66ms完成启动

    我来为你详细讲解 “GraalVM 和 Spring Native 尝鲜一步步让 Spring Boot 启动飞起来 66ms 完成启动” 的完整攻略。 什么是 GraalVM 和 Spring Native GraalVM 是一款可以运行 Java 代码的虚拟机,和其他 Java 虚拟机一样,它也可以解释字节码并执行 Java 程序。但是 GraalVM …

    Java 2023年5月19日
    00
  • 使用Java和WebSocket实现网页聊天室实例代码

    下面就是使用Java和WebSocket实现网页聊天室的完整攻略: 概述 在这个项目中,我们将使用Java 8和WebSocket技术实现一个网页聊天室。其中,Java作为服务器端语言,负责处理后台逻辑,WebSocket技术实现浏览器和服务器之间的实时通信。 实现步骤 1. 搭建WebSocket服务器 我们可以使用Java中的一个轻量级的WebSocke…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部