c,sendfile()和send()差异?[英] C, sendfile() and send() difference?

本文是小编为大家收集整理的关于c,sendfile()和send()差异?的处理方法,想解了c,sendfile()和send()差异?的问题怎么解决?c,sendfile()和send()差异?问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

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

我用来发送的任何用于发送的 - sendfile()或发送() - 在客户端,我将使用recv()对吗?

在另一面, Man Page 说:" send()和写入(2) )是标志的存在.在零标志参数的情况下,send()等同于写(2)."

推荐答案

如果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,并且要将某些文件数据复制到套接字(例如,如果您是网络服务器服务文件),则可以这样写:

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

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

.

sendfile系统调用使我们可以跳过所有复制,并让内核直接读取文件数据并在一个Fell Swoop中发送到插座上:

sendfile(sockfd, filefd, NULL, BUFSIZE);

其他推荐答案

正如您指出的,唯一的区别是标志.发送/RECV用于网络,而读/写是任何文件描述符的通用I/O函数.发送仅是有用的VS写入时,当您要使用标志时,由于标志都是与网络相关的,因此在非网络文件描述符上呼叫发送是没有意义的(我也确定它是否有效).<<<<<<<

您也应该注意:

in_fd参数必须对应于支持的文件 mmap(2)类似于操作(即,它不能是插座).

这意味着您不能从插座复制(您可以复制到插座,并且在2.6.33之前,您必须复制到套接字).

其他推荐答案

send是 A>,说:

send()函数等于用空指针 dest_len参数,如果不使用标志,则写().

sendfile是Linux特异性的.它告诉内核从文件到插座进行零拷贝I/O. (请注意,仅当源fd是文件而目标是套接字;对于通用Linux特异性零副本I/O时,请阅读有关splice().)

.

请注意,很少需要使用Linux特异性零拷贝I/O.标准和便携式read+write(或send)带有小的用户空间缓冲区(8K-16K)的循环通常会将该缓冲区保存在L1 CACHE中,从而使其等同于系统RAM的"零拷贝"观点.

因此,除非您的分析显示您的特定应用程序有所不同,请坚持标准接口.只是mho.

本文地址:https://www.itbaoku.cn/post/359391.html