作为程序员,在日常工作中,都或多或少的接触过网络I/O这个概念,接触过网络编程,听说过socket等等,但是对于更深层次的理解,多少还是有点欠缺,通过本文,可以了解网络中最重要的模块I/O,以及对几种网络模型的介绍,在我们日常工作开发过程中,可以针对特定需求,选择特定的网络模型,达到事半功倍的效果。
0
什么是I/O
通常指数据,在内部存储器和外部存储器或其他周边设备之间的输入和输出。
是信息处理系统(例如计算器)与外部世界(可能是人类或另一信息处理系统)之间的通信。输入是系统接收的信号或数据,输出则是从其发送的信号或数据。该术语也可以用作行动的一部分;到“运行I/O”是运行输入或输出的操作。
Unix 系统下,不论是标准输入还是借助套接字接受网络输入,都有两个步骤:
- 等待数据准备好(Waiting for the data to be ready)
- 从内核向进程复制数据(Copying the data from the kernel to the process)
输入/出设备是硬件中由人(或其他系统)使用与计算器进行通信的部件。例如,键盘或鼠标是计算器的输入设备,而监视器和打印机是输出设备。计算器之间的通信设备(如电信调制解调器和网卡)通常运行输入和输出操作。 简单来说,就是用户进程与内核交互,而内核与硬件进行交互。
1
阻塞式I/O模型
应用程序发起I/O系统调用,在获得结果之前,应用程序进程会一直阻塞,直到获得结果(有数据返回或者操作超时)。
默认情况下,Unix系统上的所有文件描述符都以“阻塞模式”开始。这意味着read、write或connect之类的I/O系统调用在默认情况下,都是阻塞的。
为了理解这一点,我们假如有个程序,在终端上等待标准输入(stdin),此时,假如通过调用read函数来实现该功能,那么该程序将被阻塞,直到有实际的数据可用(例如当用户在键盘上敲入字符时)。具体来说,内核将把进程置于“休眠”状态,直到数据在stdin上可用。其他类型的文件描述符也是如此。例如,如果您尝试从TCP套接字读取数据,那么read调用将阻塞,直到连接的另一端实际发送数据为止。
代码语言:javascript复制int main(int argc, char *argv[]) {
char buf[ MAX_BUFFER_LENGTH ];
int length = 0;
if( (length = read( 0, buf, MAX_BUFFER_LENGTH )) < 0 ) {
return -1;
}
buf[length] = '