首页 > 编程语言 >java bio nio aoi

java bio nio aoi

时间:2022-09-29 18:12:21浏览次数:49  
标签:bio java nio server try IOException import new

一个简单的服务器分别使用BIO NIO AOI 实现

BIO 阻塞IO 每个链接单独起来你一个线程

点击查看代码
package org.example.bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class BIOServer extends Thread {
    private ServerSocket serverSocket;
    public int getPort() {
        return serverSocket.getLocalPort();
    }
    public void run() {
        try {
            serverSocket = new ServerSocket(0);
            Executor executor = Executors.newFixedThreadPool(8);
            while (true) {
                Socket socket = serverSocket.accept();
                RequestHandler requestHandler = new RequestHandler(socket);
                executor.execute(requestHandler);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) throws IOException {
        BIOServer server = new BIOServer();
        server.start();
        try (Socket client = new Socket(InetAddress.getLocalHost(), server.getPort())) {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            bufferedReader.lines().forEach(s -> System.out.println(s));
        }
    }
}
// 简化实现,不做读取,直接发送字符串
class RequestHandler extends Thread {
    private Socket socket;
    RequestHandler(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        try (PrintWriter out = new PrintWriter(socket.getOutputStream());) {
            out.println("Hello world!");
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


BIO 非阻塞IO 多路复用 一个线程可以处理多个连接
点击查看代码
package org.example.nio;



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

public class NIOServer extends Thread {
    public void run() {
        // 创建 Selector 和 Channel
        try (Selector selector = Selector.open(); ServerSocketChannel serverSocket = ServerSocketChannel.open();) {
            serverSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 8888));
            serverSocket.configureBlocking(false);
            // 注册到 Selector,并说明关注点
            serverSocket.register(selector, SelectionKey.OP_ACCEPT);
            while (true) {
                selector.select();// 阻塞等待就绪的 Channel,这是关键点之一
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                Iterator<SelectionKey> iter = selectedKeys.iterator();
                while (iter.hasNext()) {
                    SelectionKey key = iter.next();
                    // 生产系统中一般会额外进行就绪状态检查
                    sayHelloWorld((ServerSocketChannel) key.channel());
                    iter.remove();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void sayHelloWorld(ServerSocketChannel server) throws IOException {
        try (SocketChannel client = server.accept();) {
            client.write(Charset.defaultCharset().encode("Hello world!"));
        }
    }

    public static void main(String[] args) throws IOException {
        NIOServer server = new NIOServer();
        server.start();
        try (Socket client = new Socket(InetAddress.getLocalHost(),8888)) {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            bufferedReader.lines().forEach(s -> System.out.println(s));
        }
    }

}
AIO 异步IO 基于事件和回调触发 一个线程可以服务多个连接
点击查看代码
package org.example.aio;


import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;


public class AIOServer extends Thread {

    private AsynchronousServerSocketChannel server;


    public void run() {
        String host = "localhost";
        int port = 8888;
        //ChannelGroup用来管理共享资源
        AsynchronousChannelGroup group = null;
        try {
            group = AsynchronousChannelGroup.withCachedThreadPool(Executors.newCachedThreadPool(), 10);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        try {
            server = AsynchronousServerSocketChannel.open(group);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //通过setOption配置Socket
        try {
            server.setOption(StandardSocketOptions.SO_REUSEADDR, true);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        try {
            server.setOption(StandardSocketOptions.SO_RCVBUF, 16 * 1024);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //绑定到指定的主机,端口
        try {
            server.bind(new InetSocketAddress(host, port));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println("Listening on " + host + ":" + port);
        //输出provider
        System.out.println("Channel Provider : " + server.provider());
        //等待连接,并注册CompletionHandler处理内核完成后的操作。
        server.accept(null, new AcceptCompletionHandler(server));

        //因为AIO不会阻塞调用进程,因此必须在主进程阻塞,才能保持进程存活。
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws IOException {
        AIOServer server = new AIOServer();
        server.start();
        try (Socket client = new Socket("localhost", 8888)) {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            bufferedReader.lines().forEach(s -> System.out.println(s));
        }
    }
}


class AcceptCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Object> {
    //返回参数,传入参数
    private AsynchronousServerSocketChannel channel;

    public AcceptCompletionHandler(AsynchronousServerSocketChannel channel) {
        this.channel = channel;
    }

    @Override
    public void completed(AsynchronousSocketChannel result, Object attachment) {
        System.out.println("有新客户的连接....");
        try {
            result.write(Charset.defaultCharset().encode("Hello world!"));
        } finally {
            try {
                //关闭处理完的socket,并重新调用accept等待新的连接
                result.close();
                channel.accept(null, this);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void failed(Throwable exc, Object attachment) {
        System.out.print("Server failed...." + exc.getCause());
    }
}

标签:bio,java,nio,server,try,IOException,import,new
From: https://www.cnblogs.com/guanchaoguo/p/16742515.html

相关文章

  • Java Files.walk示例
    转自:https://blog.csdn.net/cyan20115/article/details/106548324Java8中提供了Files.walk API1.列出所有文件。try(Stream<Path>walk=Files.walk(Paths.get("C:......
  • java.util.zip包 OutputStream ZipOutputStream以压缩包的方式导出
    转自:https://blog.csdn.net/lvoelife/article/details/108620182/***压缩文件*@paramfileIds文件id:根据id可获取文件*@parampackageName下载......
  • Java中抽象类和接口的介绍及二者间的区别
    转载自Java中抽象类和接口的介绍及二者间的区别 接口(Interface)和抽象类(AbstractClass)是支持抽象类定义的两种机制。一、抽象类在Java中被abstract关键字修......
  • 学校Java Week4
    Week4W4L1三元运算符(ternaryoperator)publicstaticvoidmain(String[]args){booleanisCar=true;booleanwasCar=isCar?true:false;......
  • 如何通过 Java 代码隐藏 Word 文档中的指定段落
    在编辑Word文档时,我们有时需要将一些重要信息保密。因此,可以隐藏它们以确保机密性。在本文中,将向您介绍如何通过Java程序中的代码隐藏Word文档中的特定段落。下面是......
  • Java导出带格式的Excel数据到Word表格
    前言在Word中创建报告时,我们经常会遇到这样的情况:我们需要将数据从Excel中复制和粘贴到Word中,这样读者就可以直接在Word中浏览数据,而不用打开Excel文档。在本文中,您将学习......
  • JavaScript 事件
    EVENT(上)之前我们简单的了解过一些事件,比如​​onclick​​​ /​​onload​​​ /​​onscroll​​ /...今天开始,我们详细的学习一些事件什么是事件一个事件由什么东西......
  • JavaScript 语言基础知识点
    1、JavaScript数据类型2、JavaScript变量3、Javascript运算符4、JavaScript流程控制5、JavaScript函数基础6、JavaScript数组7、JavaScript字符串函数8、JavaS......
  • 18.getElementById(id)是javascript中访问某个元素的方法
    document.getElementById(id)是javascript中访问某个元素的方法。返回指定ID的元素getElementById()方法可返回对拥有指定ID的第一个对象的引用。HTMLDOM定义了多......
  • Java方法
    Java方法一个方法只完成一个功能,利于后期拓展例如:publicclassMethods{publicstaticvoidmain(String[]args){}publicstaticintadd(inta,i......