上篇文章介绍了最基础的Socket 通信,本篇文章小鱼将继续就网络编程方向介绍下BIO 和NIO。
同步阻塞I/O,即BIO,这是最常见的I/O模型。在这种模型中,发起I/O操作的线程会被阻塞,直到操作完成。这就意味着在数据准备好之前,线程不可以执行其他任务。
在 Java 的BIO 中,服务器由ServerSocket 负责绑定ip,并且启动监听端口,去等待客户端连接。
在客户端A 的Socket 实例发起请求连接操作后,ServerSocket 接受(accept())请求连接会产生一个socket 实例,这个socket 实例就只负责与客户端A 的Socket 实例进行通信。
有上诉我们可知:同步阻塞IO 阻塞发生主要在两个地方。
在同步非阻塞I/O,即NIO,线程发起I/O请求后不会被阻塞,可以继续执行其他任务。
如果数据未准备好,I/O操作会立即返回,通常返回一个错误码表示操作不能立即完成。
在Java 中,NIO 库是在 JDK 1.4 中引入的。NIO 弥补了原来的 BIO 的不足,它在标准 Java 代码中提供了高速的、面向块的 I/O。
NIO 和 BIO 之间第一个最大的区别是:BIO 面向的是流,而 NIO 面向的是缓冲区。
BIO面向流的操作意味着数据是连续读取的,每次可以从输入流中读取一个或多个字节,直到所有数据被读取完毕。并且这些数据没有被缓存在任何地方,此外,BIO 不支持在流中前后移动数据。如果需要重新处理已读取的数据,必须先将数据存储到一个缓冲区中。BIO的面向流方法简单直观,易于理解和使用,但可能在处理大量数据或需要频繁访问数据时效率较低。
NIO 的缓冲导向方法略有不同,涉及到将数据首先读取到一个稍后处理的缓冲区中,然后需要时可以从缓冲区中前后移动处理数据,这就增加了处理过程中的灵活性。
但是,在NIO中,需要检查缓冲区是否包含所有需要处理的数据,可能需要额外的逻辑来确保数据的完整性和正确性。同时,在处理缓冲区数据时,需要确保新读取的数据不会覆盖尚未处理的旧数据。
BIO的面向流方法提供了简单的数据访问方式,但缺乏灵活性,且不支持数据的前后移动。相比之下,NIO的缓冲导向方法虽然增加了编程的复杂性,但提供了更高的灵活性和性能,特别是在需要高效处理大量数据的网络应用中。