1.相关概念
在操作系统中,程序运行的空间分为内核空间和用户空间。应用程序都是运行在用户空间的,所以它们能操作的数据也都在用户空间。
IO分两阶段(一旦拿到数据后就变成了数据操作,不再是IO):
阶段1.数据准备阶段,等待数据准备好,到达内核缓冲区(内核空间)
阶段2.内核空间复制数据到用户进程缓冲区(用户空间)阶段
1.1阻塞IO和非阻塞IO
阻塞/非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
阻塞/非阻塞主要描述的是程序请求操作系统IO操作后,如果内核数据资源没有准备好,那么程序该如何处理的问题,即阻塞IO和非阻塞IO的区别在于第一步发起系统调用是否会被阻塞。阻塞IO情况下会等待内核空间数据准备好,recvfrom的调用阻塞;而非阻塞IO下,如果内核数据资源没有准备好,会向进程返回error,进程在返回之后可以处理其他业务逻辑,过会再发起系统调用,使用线程通过轮询的方式检查内核数据资源是否准备好,直到有IO资源准备好了,在进入第二阶段,将内核空间数据资源拷贝到用户空间,recvfrom的调用总是返回。
阻塞/非阻塞在第二阶段处理过程相同。
1.2同步IO和异步IO
这两个概念是针对应用程序和操作系统的交互而言的。同步指的是用户进程触发IO操作并***等待***或者***轮询***的查看IO操作是否就绪,而异步是指用户进程触发IO操作后便开始做自己的事情,当IO操作完成会得到IO完成的通知。
2.BIO
2.1BIO介绍
BIO(blocking IO):阻塞IO
网络编程的基本模型是 C/S 模型,即两个进程间的通信。服务端提供 IP 和监听端口,客户端通过连接操作想服务端监听的地址发起连接请求,通过三次握手连接,如果连接成功建立,双方就可以通过套接字进行通信。传统的同步阻塞模型开发中,ServerSocket 负责绑定 IP 地址,启动监听端口;Socket 负责发起连接操作。连接成功后,双方通过输入和输出流进行同步阻塞式通信。 ( Socket是应用层与TCP/IP协议通信的中间软件抽象层,是应用层和传输层之间的桥梁)。简单的描述一下 BIO 的服务端通信模型:采用 BIO 通信模型的服务端,通常由一个独立的 Acceptor 线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理,处理完成后,通过输出流返回应答给客户端,线程销毁。
2.2代码实现
服务器端
//BIO 同步阻塞模型
public class BIOServer {
private ServerSocket socket;//开发工具包ServerSocket
private Scanner scanner;
private final int port = 5676;
private BufferedWriter writer;
private BufferedReader reader;
private OutputStream outputStream;
private InputStream inputStream;
public BIOServer() {
try {
socket = new ServerSocket(port);//绑定端口
scanner = new Scanner(System.in);
} catch (IOException e) {
e.printStackTrace();
}
}
//服务器端的业务逻辑
public void startTCPServer(){
try {