您的位置:首页 > 理论基础 > 计算机网络

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

2016-10-14 14:18 253 查看

一、引言         

        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
123456789
qwertyuiop

三、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 100

int 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 Hyman
hi,i
am Hyman


Github位置:

https://github.com/HymanLiuTS/NetDevelopment


克隆本项目:

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

获取本文源代码:

git checkout NL18
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐