网络编程(18)—— 使用readv和writev函数批量的进行数据的发送和读取

来源:互联网 发布:网络招聘的优点包括 编辑:程序博客网 时间:2024/06/01 11:19

一、引言         

        readv和writev函数的功能可以概括为:对数据进行整合传输以及发送。通过writev函数可以将分散保存在多个buff的数据一并进行发送,通过readv可以由多个buff分别接受数据,适当的使用这两个函数可以减少I/O函数的调用次数:

二、writev函数

函数原型:

#include<sys/uio.h>ssize_t writev(int fileds,const struct iovec* iov,int iovcnt);
fields表示数据传输对象的套接字描述符、IO描述符,文件描述符等等。

iov是iovec结构体数组,iovec结构体中包含了待发送buff的指针和大小信息。

iovcnt向第二个参数传递的数组长度。

返回实际写入的字节数

        iovec结构体定义如下:

struct iovec{   void* iov_base; //缓冲地址   size_t iov_len; //缓冲大小}

调用writev函数的示例:

#include<stdio.h>#include<string.h>#include<sys/uio.h>int main(){    struct iovec iv1,iv2;    struct iovec iovs[2];    iv1.iov_base="123456789\n";    iv1.iov_len=strlen("123456789\n");    iv2.iov_base="qwertyuiop\n";    iv2.iov_len=strlen("qwertyuiop\n");    iovs[0]=iv1;    iovs[1]=iv2;    writev(1,iovs,2);//1是标准输出缓冲区的文件描述符。    return 0;}

第6行,声明了两个iovec的结构体变量iv1和iv2;

第7行,声明了一个iovec类型的数组,数组用来存放iv1和iv2;

第9~13行,对iv1和iv2进行赋值,iov_base用来存放buffer,iov_len是buffer的大小。

第18行,调用writev函数向标准输出中写入所有buffer中的值。

        该代码的运行结果如下:

[Hyman@Hyman-PC csdn]$ ./a.out 123456789qwertyuiop

三、readv函数

#include<sys/uio.h>ssize_t readv(int fileds,const struct iovec* iov,int iovcnt);

fields表示数据传输对象的套接字描述符、IO描述符,文件描述符等等。

iov是iovec结构体数组,用来存放接收到的buffer和buffer大小。

iovcnt向第二个参数传递的数组的长度。

返回实际读出的字节数


调用readv函数的示例:

#include<stdio.h>#include<sys/uio.h>#define BUF_SIZE 100int main(){    int str_len;    struct iovec vec[2];    char buf1[BUF_SIZE]={0};    char buf2[BUF_SIZE]={0};    vec[0].iov_base=buf1;    vec[0].iov_len=5;    vec[1].iov_base=buf2;    vec[1].iov_len=BUF_SIZE;    str_len=readv(0,vec,2);//0是标准输入的文件描述符    puts(buf1);    puts(buf2);    return 0;}

第9行,声明了一个iovec类型的数组vec。

第10,11行,声明了两个char型的数组buf1,buf2用来给vec的两个iovec结构体元素。

第13~16行,分别给vec的两个结构体元素进行赋值,请注意第14行,我们给了vec[0]这个元素的iov_len的值是5,也就是说vec[0]的iov_base只会存我们输入数据的前5个字节长度。

第18行,读取标准输入的数据。

        我们运行上述程序,然后输入“hi,i am Hyman”,再打印输出时,你就会发现,字符串在am前面分开了,分别存到buf1和buf2,并进行了输出。结果如下:

[Hyman@Hyman-PC csdn]$ ./a.out hi,i am Hymanhi,i am Hyman

Github位置:

https://github.com/HymanLiuTS/NetDevelopment

克隆本项目:

git clone git@github.com:HymanLiuTS/NetDevelopment.git

获取本文源代码:

git checkout NL18


0 0