美文网首页
Java中的BIO

Java中的BIO

作者: 生不悔改 | 来源:发表于2022-03-04 17:05 被阅读0次

    什么是BIO

    BIO编程方式通常是在JDK1.4版本之前常用的编程方式。编程实现过程为:首先在服务端启动一个ServerSocket来监听网络请求,客户端启动Socket发起网络请求,默认情况下ServerSocket回建立一个线程来处理此请求,如果服务端没有线程可用,客户端则会阻塞等待或遭到拒绝。

    且建立好的连接,在通讯过程中,是同步的。在并发处理效率上比较低。大致结构如下:

    同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

    BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

    BIO能干嘛

    在通讯中,以往都是使用BIO模型去进行通信系统设计


    BIO通讯模型.png

    如图中,一个服务端可以连接多个客户端,但是接入一个客户端,服务端都需要用一个线程维持着客户端与服务端的连接。如果客户端数量很多,那么服务端也需要对应的线程数量与之连接。##如何使用BIO模型

    简单的演示:

    一对一

    服务端代码:

    /**
     * @Auther: 
     * @Date: 2021/7/9 15:27
     * @Description:
     */
    public class Server {
        public static void main(String[] args) throws IOException {
            System.out.println("服务器启动.....");
            // 1.定义一个serverSocket,并定义端口是 9999
            ServerSocket ss = new ServerSocket(9999);
            // 2.监听k客户端的socket请求
            Socket socket = ss.accept();
            // 3.从客户端传来的socket里面获取到流
            InputStream is = socket.getInputStream();
            // 4.将字节输入流包装成一个缓冲字符输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String msg;
            while((msg = br.readLine())!=null){
                System.out.println("服务端接受到信息:" + msg);
            }
        }
    }
    

    客户端代码:

    /**
     * @Auther: 
     * @Date: 2021/7/9 15:27
     * @Description:
     */
    public class Client {
        public static void main(String[] args) throws IOException {
            // 1.创建socket将对象请求服务端的链接
            Socket socket = new Socket("127.0.0.1",9999);
            // 2.从socket对象中获取一个字符输出流
            OutputStream os = socket.getOutputStream();
            PrintStream ps = new PrintStream(os);
            Scanner scanner = new Scanner(System.in);
            while(true){
                System.out.print("请说:");
                String msg = scanner.nextLine();
                ps.println(msg);
                ps.flush();
            }
        }
    }
    

    运行一下(先启动服务端,再启动客户端)
    客户端输入:

    请说:哈喽
    请说:
    

    服务端接收:

    服务器启动.....
    服务端接受到信息:哈喽
    

    一对多(使用线程实现)

    服务端代码

    /**
     * @Auther: 
     * @Date: 2021/7/9 15:27
     * @Description:
     */
    public class Server {
        public static void main(String[] args) throws IOException {
            // 1.定义一个serverSocket,并定义端口是 9999
            ServerSocket ss = new ServerSocket(9999);
            while(true){
                // 2.监听k客户端的socket请求
                Socket socket = ss.accept();
                new SocketThread(socket).start();
            }
        }
    }
    

    socket线程类

    /**
     * @Auther: 
     * @Date: 2021/7/9 15:55
     * @Description:
     */
    public class SocketThread extends Thread{
        private Socket socket;
    
        public SocketThread(Socket socket) {
            this.socket = socket;
        }
    
        @Override
        public void run() {
            try {
                // 1.从客户端传来的socket里面获取到流
                InputStream is = socket.getInputStream();
                // 2.将字节输入流包装成一个缓冲字符输入流
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String msg;
                while((msg = br.readLine())!=null){
                    System.out.println("服务端接受到信息:"+msg);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    客户端代码

    /**
     * @Auther: 
     * @Date: 2021/7/9 15:27
     * @Description:
     */
    public class Client {
        public static void main(String[] args) throws IOException {
            // 1.创建socket将对象请求服务端的链接
            Socket socket = new Socket("127.0.0.1",9999);
            // 2.从socket对象中获取一个字符输出流
            OutputStream os = socket.getOutputStream();
            PrintStream ps = new PrintStream(os);
            Scanner scanner = new Scanner(System.in);
            while(true){
                System.out.print("请说:");
                String msg = scanner.nextLine();
                ps.println(msg);
                // 推送发送内容给服务端
                ps.flush();
            }
        }
    }
    

    启动设置,允许并行启动某个程序


    image.png

    然后测试一下,分别从两个客户端发送信息服务端都会接收到,这时候启用的是两个线程,每个socket线程对象都对应一个服务端的链接。

    相关文章

      网友评论

          本文标题:Java中的BIO

          本文链接:https://www.haomeiwen.com/subject/etblrrtx.html