C,sendfile()和send()的区别?

sam*_*ara 16 c linux send sendfile

sendfile()在内核空间中的两个文件描述符之间复制数据.在某个地方,我看到如果你在Linux中用C编写Web服务器,你应该使用send()和recv()而不是使用write()和read().那么send()也使用内核空间吗?

无论我用什么发送 - sendfile()或send() - 在客户端我都会使用recv()吗?

另一方面,man page说:"send()和write(2)之间的唯一区别是标志的存在.使用零标志参数,send()等同于write(2)."

Ada*_*eld 33

如果fd是套接字文件描述符,则这些系统调用是相同的:

  • send(fd, data, length, 0) 是相同的 write(fd, data, length)
  • recv(fd, data, length, 0) 是相同的 read(fd, data, length)

因此,除非您需要设置非零flags参数,否则无论您使用send/recv还是write/read.

sendfile系统调用是一个优化.如果您有一个套接字sockfd和一个常规文件,filefd并且您想将一些文件数据复制到套接字(例如,如果您是一个提供文件的Web服务器),那么您可以这样写:

// Error checking omitted for expository purposes
while(not done)
{
    char buffer[BUFSIZE];
    int n = read(filefd, buffer, BUFSIZE);
    send(sockfd, buffer, n, 0);
}
Run Code Online (Sandbox Code Playgroud)

但是,这是低效的:这涉及内核将文件数据复制到用户空间(在read调用中),然后将相同的数据复制回内核空间(在send调用中).

sendfile系统调用让我们跳过所有的复制和有内核直接读取文件数据,并一举将其发送插槽上:

sendfile(sockfd, filefd, NULL, BUFSIZE);
Run Code Online (Sandbox Code Playgroud)