sendfile原理
    sendfile 是 Linux 系统中一个非常常用的系统调用函数,它能够实现在内核空间和用户空间之间零拷贝,是大规模文件传输中必不可少的工具。
    sendfile 的原理
    sendfile 的主要作用是将一个文件描述符中的数据传输到另外一个文件描述符中,从而避免了中间的用户空间缓冲区,以提高数据传输效率。
    sendfile 函数本质上利用了数据发送调用(send)和内存映射调用(mmap)来实现高效的文件传输。
    具体过程如下:
recv函数    1.应用程序使用 sendfile 函数向内核发出传输指令。该命令包含了源文件描述符和目标文件描述符,以及目标文件中的位移和需要传输的字节数。
    2.内核在运行 sendfile 函数时,将源文件描述符和目标文件描述符拷贝到自己的内部数据
结构中,同时使用 mmap 系统调用将目标文件映射到内核空间中。
    3.内核将页表管理数据(Page Table Entry)中相应的内存页标记为“只读”或“写时复制”。这样,内核就可以读取文件内容并且不会影响任何其他的进程。
    4.内核按照设定的位移和字节数将源文件数据直接传输到目标文件中,同时维护一定的传输进度。由于使用了内存映射技术,因此在数据传输时可以实现零拷贝。
    5.当传输完毕后,内核解除对目标文件的映射,并且从内部数据结构中删除相关的信息。
    与传统的 send 和 recv 函数不同,sendfile 可以避免通过用户空间缓存的方式,直接在文件描述符和内核交换数据,从而减少了 CPU 的运算消耗和内存复制的时间。因此,sendfile 函数在服务器端的大量广泛应用。
    sendfile 函数的优势
    使用 sendfile 函数的最大优势就是无需用户空间的中间缓存,这样不仅减少了大量的 CPU 判断调度,避免了数据复制的时间消耗,而且还优化了大规模文件传输的性能,提高了数据传输速度。同时,由于使用内核空间,因此可以更好保障系统安全性。
    在 Linux 中,sendfile 函数的调用方式也具有灵活性,可以使用 TCP 以外的协议实现高效的文件传输,如 UDP 等。
    sendfile 函数的一些限制
    1.只能用于文件到文件的传输,并且不能拷贝目录。
    2.源文件和目标文件的位移必须为块大小的整数倍 (通常是 512 字节)。
    3.源文件和目标文件必须都已经打开,且具有读写权限。
    总体而言,sendfile 函数是 Linux 中一款高效的文件传输工具,将数据直接从内核空间传输到目标文件中,在大规模文件传输处理中具有广泛的应用前景。