一 Java的IO演进
- IO模型:就是用什么样的通道或者通信模式和架构进行数据传输和接收,很大程度上决定了程序通信的性能。
- Java一个支持3种网络编程的IO模型:BIO,NIO,AIO。
实际通信下,需要根据不同的业务场景和性能需求选择不同的IO模型。
1.1 BIO
同步阻塞类(传统的阻塞型),服务器实现模式为一个连接一个线程,即客户端有连接请求时,服务器就需要启动一个线程进行处理。
- 如果这个连接不做任何事情,就会造成不必要的线程开销。
BIO适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用内。
1.2 NIO
同步非阻塞,服务器实现模式为一个线程处理多个请求(连接),即客户端发送连接请求都注册到多路复用器上面,多路复用器轮询到连接有IO请求就进行处理。
NIO适用于连接数目多且比较短的架构,比如:聊天服务器,弹幕系统,服务器间通信等。编程比较复杂,JDK1.4开始支持。
1.3 AIO
异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的IO请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
一般用于连接数较多, 且连接时间较长的应用。比如:相册服务器,充分调用OS参与并发操作。编程比较复杂,JDK1.7开始支持。
二 BIO基本介绍
BIO就是传统的 Java io 编程,其相关类和接口在 java.io 包下。
因为每一个客户端连接就需要启动一个线程进行处理,如果这个连接不做什么事情,就会造成浪费,可以通过线程池机制进行改善一下。实现多个客户端连接服务器。2.1 客户端
public class Client {public static void main(String[] args) throws IOException {Socket socket = new Socket("127.0.0.1", 9999);// 获取socket的输出流OutputStream os = socket.getOutputStream();// 包装成打印流PrintStream printStream = new PrintStream(os);printStream.println("我是一个客户端连接");printStream.flush();}}
2.2 服务端
public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(9999);Socket accept = serverSocket.accept();// 获取socket的输入流InputStream inputStream = accept.getInputStream();// 包装成缓冲流BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));String msg;if ((msg = bufferedReader.readLine()) != null) {System.out.println("服务器接收的内容:" + msg);}}}
2.3 多发和多收机制
public class Client {public static void main(String[] args) throws IOException {Socket socket = new Socket("127.0.0.1", 9999);OutputStream os = socket.getOutputStream();// 包装成打印流PrintStream printStream = new PrintStream(os);// 扫描器Scanner scanner = new Scanner(System.in);while(true){System.out.print("请输入:");String s = scanner.nextLine();printStream.println(s);printStream.flush();}}}public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(9999);Socket accept = serverSocket.accept();InputStream inputStream = accept.getInputStream();// 包装成缓冲流BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));String msg;// while将一直等待输入消息while ((msg = bufferedReader.readLine()) != null) {System.out.println("服务器接收的内容:" + msg);}}}
