sendfile函数
sendfile函数再两个文件描述符之间直接传递数据,由于该传递是在内核中,从而避免了缓冲区和用户缓冲区之间的数据拷贝,效率高。
#include<sys/senfile.h>
ssize_t sendfile(int out_id,int in_fd,off_t* offset,size_t cout);
in_fd:待读出内容的文件描述符。
out_fd: 待写入内容的文件描述符;
offset:指定读入文件流再哪个位置开始;如果为空,则使用默认读入位置;
cout: 指定再文件描述符,in_fd和out_fd之间传输的字节数。
示例代码如下:
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<unistd.h>
#include<cstdlib>
#inlude<errno.h>
#include<cstring>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/senfile.h>
#include<iostream>
using namespace std;
int main(int argc,char* argv[])
{
if (argc < 3)
{
cout<<"usage is "<<basename(argv[0])<<endl;
return 1;
}
const char* ip = argv[1];
int port = atoi(argv[2]);
const char* file_name = argv[2];
int filefd = open(file_name,O_RONLY);
assert(filefd > 0 );
struct stat stat_buf;
fstat (filefd,&stat_buf);
struct sockaddr_in address;
bzero(&address,sizeof(address));
address.sin_family = AF_INET;
inet_pton(AF_INET,ip,&address.sin_addr);
address.sin_port = htons(port);
int sock = socket(PF_INET,SOCK_STREAM,0);
assert(sock >= 0);
int ret = bind (sock,(struct sockaddr*) &address,sizeof(address));
assert(ret != -1);
ret = listen(sock,5);
assert(ret != -1);
struct sockaddr_in client;
socklen_t client_addrlength = sizeof(client);
int connfd = accept(sock, (struct sockaddr*)&client, &client_addrlength);
if(connfd < 0 )
{
cout<<"errno is"<<errno;
}
else
{
sendfile(connfd,filed,NULL,stat_buf.st_size);
close(connfd);
}
close(sock);
return 0 ;
}