【2023-04-23】 Java BIO 和 NIO

BIO:服务器实现模式为一个连接一个线程,即用户端有连接请求时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情就会造成不必要的线程开销。

BIO简单示例

//服务端
public class BIOServer {
    public static void main(String[] args) throws IOException {
        //注册服务端端口为8888,通过accept()方法获取socket
        ServerSocket serverSocket = new ServerSocket(8888);
        Socket accept = serverSocket.accept();
        //获取输入流,打印接收到的数据
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
        String msg = null;
        while ((msg = bufferedReader.readLine()) != null){
            System.out.println("服务端:"+msg);
        }
    }
}
//客户端
public class BIOClient {
    public static void main(String[] args) throws IOException {
        //连接服务端,new一个socket
        Socket socket = new Socket("localhost",8888);
        //通过输出流传递数据
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello world".getBytes());
        outputStream.flush();
        //需要关闭
        socket.close();
    }
}

多个客户端连接到一个服务端

public static void main(String[] args) throws IOException {
    //服务端
    //通过线程池来并发处理
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 10000L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100));
    ServerSocket serverSocket = new ServerSocket(8888);
    while (true){
        Socket accept = serverSocket.accept();
        threadPoolExecutor.submit(() -> {
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
                String msg = null;
                while ((msg = bufferedReader.readLine()) != null){
                    System.out.println("服务端:"+msg);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}
public static void main(String[] args) throws IOException {
    ArrayList<Integer> list = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
        list.add(i);
    }
    //通过parallelStream来模拟并发
    list.parallelStream().forEach(o->{

        try {
            Socket socket = new Socket("localhost",8888);
            OutputStream outputStream = socket.getOutputStream();
            String s = "hello world : " + o;
            outputStream.write(s.getBytes());
            outputStream.flush();
            socket.close();
            System.out.println("发送消息:"+o);
        } catch (IOException e) {
            e.printStackTrace();
        }
    });
}

NIO:服务器实现模式为一个线程处理多个请求连接,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询连接有io请求就进行处理。

NIO简单示例

//服务端
public class NIOServer {

    public static void main(String[] args) throws IOException {
        //创建通道,开启非阻塞,绑定端口
        ServerSocketChannel channel = ServerSocketChannel.open();
        channel.configureBlocking(false);
        channel.bind(new InetSocketAddress(8888));
        //创建选择器,注册通道
        Selector selector = Selector.open();
        channel.register(selector, SelectionKey.OP_ACCEPT);


        //开始监听端口,select()方法是阻塞的
        while (selector.select() > 0){
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey next = iterator.next();
                //一定要删除,不然再一次进来会报错
                iterator.remove();
                if(next.isAcceptable()){
                    //如果这个是新注册的,需要加入到select里面
                    SocketChannel socketChannel = channel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                }else if(next.isReadable()){
                    //如果是来了消息,就读取数据
                    SocketChannel channel1 = (SocketChannel)next.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int read = channel1.read(buffer);
                    if(read > 0){
                        String msg = new String(buffer.array());
                        System.out.println("服务器接收到了消息:"+msg);
                    }
                }
            }
        }
    }
}
//客户端
public class NIOClient {
    
    public static void main(String[] args) throws IOException, InterruptedException {
        InetSocketAddress localhost = new InetSocketAddress("localhost", 8888);
        SocketChannel channel = SocketChannel.open(localhost);
        channel.configureBlocking(false);

        String name = Thread.currentThread().getName();
        Scanner scanner = new Scanner(System.in);
        String line;
        while ((line = scanner.nextLine()) != null){
            String s = name + "说:" + line;
            ByteBuffer wrap = ByteBuffer.wrap(s.getBytes());
            if(!channel.finishConnect()){
                while (!channel.finishConnect()){
                    Thread.sleep(100);
                }
            }
            channel.write(wrap);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值