Java BIO工作机制介绍

2024年 1月 2日 26.0k 0

Java BIO基本介绍

  • Java BIO 就是传统的 java io  编程,其相关的类和接口在 java.io
  • BIO(blocking I/O) : 同步阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需 要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制改善(实现多个客户连接服务器).

图片[1]-Java BIO工作机制介绍-不念博客

2. Java BIO工作机制

图片[2]-Java BIO工作机制介绍-不念博客

对BIO编程流程的梳理

  • 服务器端启动一个 ServerSocket,注册端口,调用accpet方法监听客户端的Socket连接。
  • 客户端启动 Socket 对服务器进行通信,默认情况下服务器端需要对每个客户 建立一个线程与之通讯
  • 3.  传统的BIO编程实例回顾

    在传统的BIO(Blocking I/O)编程模型中,客户端(Client)和服务端(Server)之间的通信是基于同步阻塞方式进行的。 在这种模型下,服务端使用ServerSocket来绑定IP地址和监听端口,并启动监听。客户端则使用Socket来发起连接请求。

    当客户端发起连接请求后,服务端接受连接并创建一个新的Socket与客户端进行通信。通信过程中,双方通过输入流和输出流进行数据的读取和写入。

    在这种同步阻塞模型下,客户端和服务端是完全同步、完全耦合的关系。这意味着当客户端向服务端发送请求时,客户端会一直等待直到服务端响应完成;而服务端在处理客户端请求时也会一直阻塞,直到请求处理完成后才能继续处理下一个请求。当有大量的并发连接时,每个连接都需要独占一个线程来处理,导致资源消耗过高,无法支持高并发场景。

    客户端案例如下

    package com.zbbmeta.client;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.PrintStream;
    import java.net.Socket;
    /**
     目标: Socket网络编程。
    
     Java提供了一个包:java.net下的类都是用于网络通信。
     Java提供了基于套接字(端口)Socket的网络通信模式,我们基于这种模式就可以直接实现TCP通信。
     只要用Socket通信,那么就是基于TCP可靠传输通信。
    
     功能1:客户端发送一个消息,服务端接口一个消息,通信结束!!
    
     创建客户端对象:
     (1)创建一个Socket的通信管道,请求与服务端的端口连接。
     (2)从Socket管道中得到一个字节输出流。
     (3)把字节流改装成自己需要的流进行数据的发送
     创建服务端对象:
     (1)注册端口
     (2)开始等待接收客户端的连接,得到一个端到端的Socket管道
     (3)从Socket管道中得到一个字节输入流。
     (4)把字节输入流包装成自己需要的流进行数据的读取。
    
     Socket的使用:
     构造器:public Socket(String host, int port)
     方法:  public OutputStream getOutputStream():获取字节输出流
     public InputStream getInputStream() :获取字节输入流
    
     ServerSocket的使用:
     构造器:public ServerSocket(int port)
    
     小结:
     通信是很严格的,对方怎么发你就怎么收,对方发多少你就只能收多少!!
    
     */
    public class BioClient01 {
        public static void main(String[] args) throws IOException {
            System.out.println("==客户端的启动==");
            // (1)创建一个Socket的通信管道,请求与服务端的端口连接。
            Socket socket = new Socket("127.0.0.1",8899);
            // (2)从Socket通信管道中得到一个字节输出流。
            OutputStream os = socket.getOutputStream();
            // (3)把字节流改装成自己需要的流进行数据的发送
            PrintStream ps = new PrintStream(os);
            // (4)开始发送消息
            ps.println("我是客户端,我想约你吃小龙虾!!!");
            ps.flush();
        }
    }

    服务端案例如下

    package com.zbbmeta.server;
    
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class BioServer01 {
        public static void main(String[] args) throws IOException {
            System.out.println("==服务器的启动==");
            // (1)注册端口
            ServerSocket serverSocket = new ServerSocket(8899);
            //(2)开始在这里暂停等待接收客户端的连接,得到一个端到端的Socket管道
            Socket socket = serverSocket.accept();
            //(3)从Socket管道中得到一个字节输入流。
            InputStream is = socket.getInputStream();
            //(4)把字节输入流包装成自己需要的流进行数据的读取。
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            //(5)读取数据
            String line ;
            while((line = br.readLine())!=null){
                System.out.println("服务端收到:"+line);
            }
        }
    }

    小结

    • 在Java BIO中,确实存在服务端一直等待客户端消息的情况。如果客户端没有发送消息,服务端将一直阻塞在读取操作上,无法继续执行后续代码
    • 服务端按行获取消息是一种常见的处理方式,即服务端通过BufferedReader逐行读取客户端发送的消息。因此,客户端也需要按行发送消息,以便服务端可以正确地解析和处理
    • 面对大量并发连接时,每个连接都需要独占一个线程来处理,这会导致资源消耗过高,无法支持高并发场景

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论