sendfile函数

sendfile函数:

函数原型:

      #include

       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 必须是真实存在的文件,不能是socket和管道

out_fd 必须是一个socket.

测试代码:

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include

ser.c文件:

#include"../utili.h"

int main(int argc,char *argv[])
{
    if(argc<=3)
    {
        printf("usage: %s  ip  port_number\n",basename(argv[0]));
        return 1;
    }
    const char*ip = argv[1];
    int port = atoi(argv[2]);
    const char *file_name = argv[3];

    int filefd = open(file_name,O_RDONLY);
    assert(filefd>0);
    struct stat stat_buf;
    fstat(filefd,&stat_buf);

    struct sockaddr_in address;
    bzero(&address,sizeof(address));
    address.sin_family = AF_INET;
    address.sin_port = htons(port);
    inet_pton(AF_INET,ip,&address.sin_addr);

    int sock = socket(AF_INET,SOCK_STREAM,0);
    assert(sock>=0);
    socklen_t len = sizeof(address);
    int ret = bind(sock,(struct sockaddr*)&address,len);
    assert(ret!=-1);

    ret = listen(sock,5);
    assert(ret!=-1);

    struct sockaddr_in client;
    socklen_t client_len = sizeof(client);
    int connfd = accept(sock,(struct sockaddr*)&client,&client_len);
    if(connfd<0)
    {
        printf("errno: %d\n",errno);
    }
    else
    {
        sendfile(connfd,filefd,NULL,stat_buf.st_size);
        close(connfd);
    }
close(sock);
return 0;
}
cli.c文件:

#include"../utili.h"

int main(int argc,char *argv[])
{
    const char *ip = argv[1];
    int port = atoi(argv[2]);

    struct sockaddr_in addrSer;
    bzero(&addrSer,sizeof(addrSer));
    addrSer.sin_family = AF_INET;
    addrSer.sin_port = htons(port);
    inet_pton(AF_INET,ip ,&addrSer.sin_addr);

    int sock = socket(AF_INET,SOCK_STREAM,0);
    assert(sock>=0);
    
    int ret = connect(sock,(struct sockaddr*)&addrSer,sizeof(addrSer));
    assert(ret>=0);

    char buf[50];

    while(1)
    {
        ret = recv(sock,buf,50,0);
        if(ret<0)
        break;
        else if(ret == 0)
        {
            printf("sever close connextion\n");
            break;
        }
        else
        printf("get %d bytes :  %s\n",(int)strlen(buf),buf);
    }
    close(sock);
}



你可能感兴趣的:(sendfile函数)