Java BIO

25 阅读1分钟

基本介绍

image.png

工作机制

image.png

BIO编程简单流程

image.png

案例

image.png

package cn.meowrain.bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * BIO(Blocking I/O)模型服务器示例
 * 一个线程处理一个客户端连接,通过线程池复用线程资源。
 */
public class BIOServer {

    public static void main(String[] args) {
        // 启动服务器
        new BIOServer().start(6666);
    }

    /**
     * 启动服务器监听指定端口
     */
    public void start(int port) {
        // 定义线程命名规则
        AtomicInteger counter = new AtomicInteger(1);

        // 创建线程池(推荐参数设置)
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                3,                       // 核心线程数
                6,                       // 最大线程数
                60L,                     // 空闲线程存活时间
                TimeUnit.SECONDS,        // 时间单位
                new LinkedBlockingQueue<>(50),  // 有界队列,防止OOM
                r -> {
                    Thread t = new Thread(r);
                    t.setName("bio-worker-" + counter.getAndIncrement());
                    t.setDaemon(false);
                    t.setUncaughtExceptionHandler((thread, ex) ->
                            System.err.println("[ERROR] " + thread.getName() + " 出现异常:" + ex.getMessage())
                    );
                    return t;
                },
                new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:主线程执行任务,防止丢任务
        );

        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("🚀 BIO服务器启动成功,监听端口:" + port);

            // 主循环:不断接收客户端连接
            while (true) {
                System.out.println("等待客户端连接...");
                Socket socket = serverSocket.accept(); // 阻塞
                System.out.println("✅ 客户端已连接:" + socket.getRemoteSocketAddress());

                // 提交到线程池处理
                pool.execute(() -> handleClient(socket));
            }

        } catch (IOException e) {
            System.err.println("服务器启动异常:" + e.getMessage());
        }
    }

    /**
     * 处理客户端逻辑(读取数据)
     */
    private void handleClient(Socket socket) {
        System.out.println("🧵 线程启动:" + Thread.currentThread().getName());
        try (InputStream inputStream = socket.getInputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) { // 阻塞读取
                String msg = new String(buffer, 0, len);
                System.out.println("📨 收到来自 " + socket.getRemoteSocketAddress() + " 的消息:" + msg.trim());
            }
        } catch (IOException e) {
            System.err.println("⚠️ 客户端 " + socket.getRemoteSocketAddress() + " 断开连接。");
        } finally {
            try {
                socket.close();
                System.out.println("🔌 关闭连接:" + socket.getRemoteSocketAddress());
            } catch (IOException e) {
                System.err.println("关闭连接异常:" + e.getMessage());
            }
        }
    }
}

image.png