网络IO

概念说明

文件描述符

Linux 的内核将所有外部设备都看做一个文件来操作(一切皆文件),描述符就是一个数字,指向内核中的一个结构体(文件路径,数据区等一些属性)。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符,或者可以说对一个文件的读写操作会调用内核提供的系统命令,然后返回一个file descriptor(fd,文件描述符)。而对一个socket的读写也会有响应的描述符,称为socket fd(socket文件描述符),服务端接收到客户端连接就会创建一个文件描述符。

Socket是什么

可能很多人对socket的认识是:通过socket可以实现一个简单的网络通信,并不知道它的设计思路和使用它时到底干了啥。

 

服务端处理网络请求的大致流程

图片

核心过程:

(1)成功建立连接。

(2)内核等待网卡数据到位。(这里涉及DMA技术)(这一步控制IO是否阻塞)

(2)内核缓冲区数据拷贝到用户空间(这里涉及mmap内存映射技术)。(这一步控制IO是否同步)

大致解释下DMA和mmap:

DMA技术:网卡和磁盘数据拷贝到内存这个过程,如果需要CPU参与的话会占用大量的CPU运行时间,因为IO操作相对耗时非常高。而且CPU主要适用于进行运算,磁盘数据拷贝到内存这个过程并不涉及到运算操作而且流程固定,因此设计了DMA来专门进行上述拷贝操作,相当于在磁盘嵌入了一个DMA芯片(类似简易版的IO cpu)让它来专门负责上述拷贝操作,从而使得CPU不参与上述拷贝操作,使之专注于运算操作。

mmap的设计理念是:用户空间和内核空间映射同一块内存空间,从而达到省略将数据从内核缓冲区拷贝到用户空间的操作,用户空间通过映射直接操作内核缓冲区的数据。零拷贝(就是数据不经过用户空间,直接在内核空间进行操作)就是利用的mmap技术来实现的。

用户空间 和 内核空间

现在操作系统都是采用虚拟存储器,那么对 32 位操作系统而言,它的寻址空间(虚拟存储空间)为 4G(2 的 32 次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核,保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对 linux 操作系统而言(以 32 位操作系统为例)

每个进程可以通过系统调用进入内核,因此,Linux 内核由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有 4G 字节的虚拟空间。

网络IO模型

同步阻塞IO

同步非阻塞IO

I/O 多路复用

信号驱动IO

进程调用系统io后,进程处理其他事务等待系统检测到缓冲区有数据,发送信号给进程,进程收到信号后挂起等待系统将数据拷贝到进程用户空间(只在数据拷贝阶段阻塞)

异步IO

进程调用系统io后,离开直到内核接收到数据并将数据从内核空间复制到进程的用户空间后,内核才给小进程发送信号,全程没有阻塞