基本介绍
- Java BIO 就是传统 Java IO 编程。
- BIO 即 blocking io 同步阻塞,一个连接一个线程,当有一个客户端加入时服务器需要启动一个线程进行处理。
- 适用于连接数目较小且比较固定的架构,不适合高并发
编程简单流程
- 服务端启动一个 ServerSocket
- 客户端启动 Socket 对服务器进行通信,默认情况下服务器端需要对每个客户建立一个线程与之通信
- 客户端发出请求后,先咨询服务器是否有线程响应,如果没有则会等待,或者遭到拒绝
- 如果有响应,客户端会等待请求结束后,再继续执行
示意图
graph TD
a[Server]
b1[Thread1]
b2[Thread2]
b3[Thread3]
c1[Read/Write]
c2[Read/Write]
c3[Read/Write]
d1[Client1]
d2[Client2]
d3[Client3]
a-->b1-->c1-->d1
a-->b2-->c2-->d2
a-->b3-->c3-->d3
程序实例
package com.example.chatnetty.bio;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
* BIO 模型中,每当一个客户端连接时,都会创建一个线程,并且在线程中与客户端通信
public static void main(String[] args) throws IOException {
ExecutorService pool = Executors.newCachedThreadPool();
ServerSocket serverSocket = new ServerSocket(6666);
System.out.println("服务器启动了");
final Socket socket = serverSocket.accept();
System.out.println("连接到一个客户端");
pool.execute(new Runnable() {
public static void handler(Socket socket) {
byte[] bytes = new byte[1024];
InputStream is = socket.getInputStream();
int len = is.read(bytes); // 在 read 时会阻塞
System.out.println("当前线程:" + Thread.currentThread().getName() +
",收到数据:" + new String(bytes, 0, len));
} catch (IOException e) {
System.out.println("关闭client连接");
} catch (IOException e) {