栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 的 BIO和NIO简介及聊天室Demo

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 的 BIO和NIO简介及聊天室Demo

java有三钟io模型:分别是BIO,NIO,AIO,

BIO

BIO: 同步阻塞型io. 传统的Socket编程即BIO, 一个连接需要一个线程处理.

基于BIO即 Socket实现的聊天demo
代码示例:

服务端:

package com.czy.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class ServerDemo {

    public static void main(String[] args) throws IOException {
        //1.创建线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        //2.服务端创建ServerSocket 对象 绑定服务端监听端口
        ServerSocket serverSocket = new ServerSocket(9090);
        while (true){
            //3. 服务端 阻塞监听socket连接
            Socket socket = serverSocket.accept();
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    //4. 业务处理读取和写入数据
                    handle(socket);
                }
            });
        }
    }


    private static void handle(Socket socket){
        try {
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int read = inputStream.read(bytes);
            System.out.println("客户端:"+new String(bytes,0,read,StandardCharsets.UTF_8));
            Scanner scanner = new Scanner(System.in);
            String s = scanner.nextLine();
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(s.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端:

package com.czy.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;


public class ClientDemo {

    public static void main(String[] args) throws IOException {
        while (true){
            //1.创建Socket对象  绑定主机和端口,
            Socket socket = new Socket("127.0.0.1",9090);

            //2.创建输出流,便于后续socket向客户端发送数据
            OutputStream outputStream = socket.getOutputStream();
            Scanner scanner = new Scanner(System.in);
            String s = scanner.nextLine();

            // 3.向输出流中写入数据
            outputStream.write(s.getBytes(StandardCharsets.UTF_8));

            // 4.读取服务端发送的数据
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int read = inputStream.read(bytes);
            System.out.println("服务端:"+new String(bytes,0,read,StandardCharsets.UTF_8));

            // 5.关闭流
            socket.close();
        }
    }
}

NIO NIO简介:

同步非阻塞型io,一个线程处理多个连接请求,客户端发送的连接请求会注册到多路复用器上,多路复用器轮询到有IO请求的连接就进行处理

NIO三大核心概念的关系:

下图描述了NIO的Selector(选择器),Channel(通道)和Buffer(缓存区)的关系

1.一个客户端连接一个Channel,对应一个Buffer,
2.每条Channel都会注册到Selector上,Selector轮询Channel上事件,Selector根据不同的事件处理
3.Buffer本质上是数组,不同与BIO的是BIO只能读或者只能写,NIO的buffer是双向的,可读可写.

代码示例:基于NIO实现的聊天Demo: 该demo是未加Selector的编程的.有点繁杂,感兴趣的可以自行百度

客户端:

public class NIOClient {

    public static void main(String[] args) throws IOException {
        //1.打开通道
        SocketChannel socketChannel = SocketChannel.open();
        //2.绑定对应的端口
        socketChannel.connect(new InetSocketAddress("127.0.0.1",9999));
        //3.向缓冲区中写入数据
        socketChannel.write(ByteBuffer.wrap("老板,还钱吧".getBytes(StandardCharsets.UTF_8)));

        //4.申请缓冲区读取服务端信息
        ByteBuffer allocate = ByteBuffer.allocate(1024);
        int read = socketChannel.read(allocate);
        System.out.println("服务端消息:"+new String(allocate.array(),0,read,StandardCharsets.UTF_8));
        socketChannel.close();
    }
}

服务端:

public class NIOServer {
    public static void main(String[] args) throws IOException, InterruptedException {

        //1.打开服务端通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        //2.绑定对应的端口号
        serverSocketChannel.bind(new InetSocketAddress(9999));

        //3.通道默认是阻塞的,需要设置成非阻塞
        serverSocketChannel.configureBlocking(false);

        System.out.println("服务端启动成功...");

        while (true){
            //4.检查是否有客户端连接, 有客户端连接会返回对应的通道
            SocketChannel socketChannel = serverSocketChannel.accept();
            if (socketChannel == null){
                System.out.println("没有客户端连接...");
                Thread.sleep(3000);
                continue;
            }
            //5.获取客户端传递过来的数据,并将数据发在缓冲区中
            ByteBuffer allocate = ByteBuffer.allocate(1024);
            //返回值:正数本地没有读到有效字节数
            //0:表示本地没有读到数据
            //-1表示读到末尾
            int read = socketChannel.read(allocate);
            System.out.println("客户端消息: "+new String(allocate.array(),0,read, StandardCharsets.UTF_8));
            //6.向客户端返会数据
            socketChannel.write(ByteBuffer.wrap("没钱".getBytes(StandardCharsets.UTF_8)));
            //7.关闭连接
            socketChannel.close();
        }
    }
}
NIO与BIO的比较:

1.BIO是以流的方式处理数据的,而NIO以缓冲区的方式处理数据,缓冲区IO效率比流IO的效率高很多
2.BIO是阻塞的,NIO则是非阻塞的
3.BIO一个线程处理一个连接请求,而NIO有选择器可以实现单线程监听多个客户端连接.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028902.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号