一.存在的缓冲区:
- 用户态自定义的缓冲区;
- 内核(TCP/IP)维护的缓冲区:send buffer 和 recv buffer ,统称为socket buffer.
二.用户数据发送与接收过程:
发送过程:
假如需要将磁盘上的数据发送给网络上的其他用户,需要经历这几个过程:
- 首先会经历一系列的系统调用将数据加载到内核的缓冲区,然后将数据再拷贝到用户空间缓冲区;
可不可以直接将数据从硬盘拷贝到用户空间呢?
可以,有些程序或者提高效率和性能,会实现“内核旁路”功能,
避过内核参与,直接在磁盘与用户缓冲区进行数据的传输,多数情况为了稳定,还是走正常流程吧。
- 当数据在用户空间操作完之后,会调用send等系统调用,将数据从用户空间拷贝到TCP的接收缓冲区;
- 最后一般在将数据从内核通过DMA技术将数据发送给网卡,因为此时数据不用我们进行计算修改之类的操作,直接进行拷贝即可,所以用DMA。
内核常驻内存,所以内核空间数据一定在内存上,内存和网卡都属于高速设备,
使用DMA传输再好不过了!
接收过程:
- 数据经历物理层到达网卡,一般也是通过DMA技术将数据传输到内核缓冲区,也就是TCP的接收缓冲区;
- 然后用户调用read()/recv()等系统调用将数据从内核缓冲区读取到用户自己定义的缓存区中。
三.DMA技术 :Direct Memory Access直接内存存取
DMA 传输将数据从一个地址空间复制到另外一个地址空间。
当CPU 初始化这个传输动作,传输动作本身是由 DMA 控制器来实行和完成,
也就是说除了初始化的时候需要cpu工作,传输的过程是脱离CPU的,是不需要CPU工作的。
典型的例子就是上面说到的内存与网卡等设备之间的传输
与普通的数据拷贝相比:
普通数据的拷贝需要经过cpu,而DMA数据的传输过程中不需要经过cpu。
像是这样的操作并没有让处理器工作拖延,反而可以被重新排程去处理其他的工作。
讲到这里,在提一个linux中文件传输性能比较高的函数sendfile().