关闭

linux高级I/O函数sendfile

标签: 网络编程linux系统调用
719人阅读 评论(0) 收藏 举报
分类:

sendfile函数,顾名思义,用于传输文件而设计的函数。是linux下的系统调用函数。

函数原型:

#include<sys/sendfile.h>
ssize_t sendfile(int out_fd,int in_fd,off_t* offset,size_t count);

sendfile函数在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了内核缓冲区和用户缓冲区之间的数据拷贝,效率很高,这被称为零拷贝。

函数参数:

  • out_fd参数是代写入内容的文件描述符。
  • in_fd参数是待读出内容的文件描述符。
  • offset参数指定从读入文件流的哪个位置开始读,如果为空,则使用读入文件流默认的起始位置。
  • count参数指定在文件描述符in_fd和out_fd之间传输的字节数。

几点说明:

  • in_fd必须是一个支持类似mmap函数的文件描述符,即它必须指向真实文件,不能是socket和管道。
  • 在Linux2.6.33之前,out_fd必须是一个socket,而从Linux2.6.33之后,out_fd可以是任何文件。这意味着我们不仅可以用该函数在网络上传输文件,还可以使用该函数对本地的文件实现拷贝操作。

返回值:

sendfile成功时返回传输的字节数,失败则返回-1并设置errno。

与read和write系统调用函数的比较:

我们称sendfile函数为零拷贝函数,效率很高。那效率高到底体现在哪里了呢?
比如说客户端想把本地的一个文件通过socket发送给服务器,我们分析一下使用read&write和使用sendfile函数实现的差别:

如果我们使用read和write函数,需要进行如下几个步骤:
1. 调用read函数,文件数据被copy到内核缓冲区
2. read函数返回,文件数据从内核缓冲区copy到用户缓冲区
3. write函数调用,将文件数据从用户缓冲区copy到内核与socket相关的缓冲区。
4. 数据从socket缓冲区copy到相关协议引擎。

以上细节是传统read/write方式进行网络文件传输的方式,我们可以看到,在这个过程当中,文件数据实际上是经过了四次copy操作:
硬盘—>内核buf—>用户buf—>socket相关缓冲区—>协议引擎

而使用sendfile函数,需要进行如下几个步骤:
1. sendfile系统调用,文件数据被copy至内核缓冲区
2. 再从内核缓冲区copy至内核中socket相关的缓冲区
3. 最后再socket相关的缓冲区copy到协议引擎

对比我们可以得出,相比使用sendfile函数,Read & Write方式带来的性能损耗主要有两点:
1. 不必要的内存拷贝。即多了一次从内核缓冲区到用户缓冲区的数据拷贝。
2. 系统调用带来的额外的用户态/内核态上下文切换。我们知道,使用系统调用会发生从内核态到用户态之间的相互转换。使用read&write方式,多使用了一次系统调用,就多了一次上下文切换,降低了性能。

综上我们可以得出,sendfile函数不但能减少切换次数而且还能减少拷贝次数,是一个非常高效的数据拷贝函数,尤其在传输一个非常大的文件时,sendfile函数的高性能体现的更为明显。因此,在以后我们设计到网络传输文件时,应该使用sendfile函数,提高效率。

0
0
查看评论

Linux "零拷贝" sendfile函数

Sendfile函数说明 #include ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); sendfile()是作用于数据拷贝在两个文件描述符之间的操作函数.这个拷贝操作是内核中操作的,所以称为...
  • chunlovenan
  • chunlovenan
  • 2015-04-02 17:25
  • 2695

sendfile函数

sendfile函数在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了内核缓冲区和用户缓冲区之间的数据拷贝,效率很高,这被称为零拷贝。sendfile函数的定义如下:#include <sys/sendfile.h> ssize_t sendfile(int out_fd,...
  • tengyft
  • tengyft
  • 2015-05-19 15:18
  • 1258

Linux网络编程--sendfile零拷贝高效率发送文件

本博文介绍使用sendfile函数进行零拷贝发送文件,实现高效数据传输,并对其进行验证。 那么什么是sendfile呢? linux系统使用man sendfile,查看sendfile原型如下: #include        ssize_t sendfi...
  • u010193457
  • u010193457
  • 2016-03-11 15:24
  • 8157

tcp传输图片(发送端使用sendfile函数)

 客户端client向服务器server发送一幅图片,使用tcp传输:   服务器代码: #include sys/socket.h> #include sys/types.h> #include stdlib.h> #inc...
  • mianhuantang848989
  • mianhuantang848989
  • 2017-06-21 18:18
  • 204

Linux下利用sendfile函数传输文件

#include #include #include #include #include #include #include #include #include #include #include #include #include int main() { co...
  • tlzhatao
  • tlzhatao
  • 2015-03-09 16:08
  • 656

sendfile详解

在apache,nginx,lighttpd等web服务器当中,都有一项sendfile相关的配置,在一些网上的资料都有谈到sendfile会提升文件传输性能,那sendfile到底是什么呢?它的原理又是如何呢? 在传统的文件传输里面(read/write方式),在实现上其实是比较复杂...
  • eastlhu
  • eastlhu
  • 2016-06-21 09:37
  • 727

sendfile原理,实现文件传输性能的提升

在apache,nginx,lighttpd等web服务器当中,都有一项sendfile相关的配置,在一些网上的资料都有谈到sendfile会提升文件传输性能,那sendfile到底是什么呢?它的原理又是如何呢?  在传统的文件传输里面(read/write方式),在实现上其实是比较复杂...
  • wm_1991
  • wm_1991
  • 2016-07-15 11:16
  • 1967

sendfile函数--零拷贝

零拷贝:零拷贝技术可以减少数据拷贝和共享总线操作的次数,消除通信数据在存储器之间不必要的中间拷贝过程,有效地提高通信效率,是设计高速接口通道、实现高速服务器和路由器的关键技术之一。 sendfile#include <sys/sendfile.h> ssize_t sendfile(i...
  • hello_bravo_
  • hello_bravo_
  • 2016-11-01 19:11
  • 593

Zero-Copy&sendfile浅析

<br />一、典型IO调用的问题<br />一个典型的web服务器传送静态文件(如CSS,JS,图片等)的过程如下:<br /><br />read(file, tmp_buf, len);<br />write(socket, tmp_...
  • JiangBo_HIT
  • JiangBo_HIT
  • 2011-01-17 11:53
  • 7099

Nginx --sendfile配置

Nginx高级篇sendfile配置 sendfile: 设置为on表示启动高效传输文件的模式。sendfile可以让Nginx在传输文件时直接在磁盘和tcp socket之间传输数据。如果这个参数不开启,会先在用户空间(Nginx进程空间)申请一个buffer,用read函数把数据从磁盘读到ca...
  • u011363729
  • u011363729
  • 2017-04-26 16:50
  • 3962
    个人资料
    • 访问:140916次
    • 积分:2188
    • 等级:
    • 排名:千里之外
    • 原创:69篇
    • 转载:2篇
    • 译文:0篇
    • 评论:84条
    博客专栏
    最新评论