首页 > 代码库 > 高级I/O函数(1)-writev、readv、sendfile函数

高级I/O函数(1)-writev、readv、sendfile函数

 1.前言

   Linux提供了很多的高级I/O函数,它们在特定的条件下表现出优秀的特性。这里主要讨论的是和网络编程相关的几个。

  用于读写数据的函数,包括writev/readv、sendfile。

  readv和writev函数

#include <sys/uio.h>ssize_t readv(int fd,const struct iovec* vector,int count);ssize_t writev(int fd,const struct iovec* vector,int count);

struct iovec{
void *iov_base;/*内存的起始地址*/
size_t iov_len; /*内存的长度*/
};

/*fd参数是被操作的文件描述符。结构体iovec描述的是一块内存。count参数是vector数组的长度,即有多少块内存数据需要从fd读出或写到fd。*/
返回值:readv和writev在成功时返回读出或写入fd的字节数。失败时则返回-1并设置errno.

 

  sendfile函数

1 #include <sys/sendfile.h>2  ssize_t sendfile(int out_fd,int in_fd,off_t* offset,size_t count);3 /*返回值:成功时返回传输的字节数,失败时则返回-1并设置errno.

函数说明:

  •    in_fd参数是待读出内容的文件描述符,out_fd是待写入内容的文件描述符。offset参数指定从读入文件流的哪个位置开始读,如果为空,则使用读入文件流默认的起始位置。count参数指定在文件描述in_fd和out_fd之间的传输的字节数。
  •   in_fd必须指向真实的文件,不能使socket的管道;而out_fd则必须是一个socket。因此可知,sendfile函数几乎是专门为了网络上传输文件而设计的。
  • 下面是利用sendfile函数将服务器上的一个文件传送给客户端
 1 /*****************利用sendfile函数传送文件***************/ 2  3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <arpa/inet.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <assert.h>10 #include <errno.h>11 #include <fcntl.h>12 #include <sys/sendfile.h>13 14 int main(int argc,const char* argv[]){15      if(argc<=3){16            printf("usage:%s ip_addresport_number filename\n",argv[0]);17            return -1;18      }19 20      const char* ip=argv[1];21      int  port=atoi(argv[2]);22      23      int filefd=open(argv[3],O_RDONLY);24      assert(filefd!=-1);25     26      struct stat stat_buf;27      fstat(filefd,&stat_buf);28       29      struct sockaddr_in address;30      bzero(&address,sizeof(address));31      address.sin_family=AF_INET;32      inet_pton(AF_INET,ip,&address.sin_addr);33      34      int sock=socket(AF_INET,SOCK_STREAM,0);35      assert(sock!=-1);36 37 38       int ret=bind(sock,(strucsockaddr*)&address,sizeof(address));39       assert(ret!=-1);40      41       ret=listen(sock,5);42       assert(ret!=-1);43 44       struct sockaddr_in client;45       socklen_t addrlen;46       int connfd=accept(sock,(struct sockaddr*)&client,&addrlen);47       if(connfd<0){48             printf("errno is:%d \n",errno);49       }    50       51       else{52            sendfile(connfd,filefd,NULL,stat_buf.st_size);53            close(connfd);54        }55       56         close(sock);57         return 0;58 }

/*代码没有为目标文件分配任何用户空间的缓存,也没有执行读取文件的操作,但同样实现了文件的发送,其效率显然要高得很多.*/

 

高级I/O函数(1)-writev、readv、sendfile函数