一 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);
}
}
}