IO 是什么
IO,也就是 input/output,输出和输入。
咱们开发各种程序,实质上都是为了数据。数据须要存储和传输,就须要 IO。
平时波及的 IO 次要是磁盘 IO 和网络 IO,本系列次要记录网络 IO。
根底概念 - 用户空间和内核空间
首先咱们先来看内核态和用户态。
咱们晓得软件性能的实现是须要硬件反对的,软件的底层就是对硬件的操作,比方读取内存、读取文件等。然而,如果每个软件都能够间接任意操作硬件,那么势必会造成凌乱。那么就须要依据软件的应用场景,来划分不同的硬件操作权限。内核态和用户态就是这么一种状态用来划分不同的资源操作权限。
在具体实现上,应用了分层和封装的形式。内核态能够调用所有系统资源,而用户态只能通过内核态封装的零碎调用来操作资源。这些零碎调用依据权限设计,凋谢肯定范畴的权限用于操作资源。
内核态和用户态对应的内存空间,就是内核空间和用户空间。两个内存空间之间互相隔离不影响。
咱们来看断代码
int money = 100 * 30; // 我在用户空间
String text = String.format("我这个月赚了 %s", money); // 我是在用户空间
OutputStream outputStream = new FileOutputStream("bookKeep.txt");
outputStream.write(text.getBytes(StandardCharsets.UTF_8)); // 我在内核空间
下面的代码中,逻辑计算时在用户空间,当进行文件操作时,转入内核空间。能够查看到 outputStream.write 最终调用的是 native 办法。
总之,咱们要晓得的是,内核空间和用户空间是互相独立的,咱们的应用程序是在用户空间执行的。
网络 IO 的流程
下面这张图是从数据传输的角度,形容了读取和写入数据时的流程。
读取数据时:数据从网卡缓冲区 -> 内核缓冲区 -> 用户缓冲区。
写入数据时:数据从用户缓冲区 -> 内存缓冲区 -> 网卡缓冲区。
Socket
那么在具体代码层面,咱们怎么进行操作呢?
从后面的内核空间和用户空间的形容中能够晓得,咱们的的应用程序是在用户空间内工作的,如果须要操作资源,就须要通过零碎调用来进入内核空间,而这个零碎调用调用就是 Socket。Socket 是操作系统提供给应用程序的一组操作网络资源的接口。
用一张图示意:
Socket 的流程:
总结
本篇文章是网络 IO 的第一篇,次要讲述了网路 IO 的一些根底概念,包含内核空间 - 用户空间、网络 IO 的流程以及 Socket。重点是 TCP/IP 网络体系、内核空间 - 用户空间以及 Socket 的关系。前面咱们将开始讲述各种网络 IO 模型。