如果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);
}
然而,这是低效的:这涉及内核将文件数据复制到用户空间(在read
调用中),然后将相同的数据复制回内核空间(在send
调用中)。
系统sendfile
调用让我们跳过所有的复制,让内核直接读取文件数据并一举将其发送到套接字上:
sendfile(sockfd, filefd, NULL, BUFSIZE);