您的位置:首页 > 其它

write read;writev readv;recv send;recvfrom sendto;recvmsg sendmsg五组I/O函数汇总

2015-04-23 15:03 621 查看

read、write

头文件: #include <unistd.h>

原型:size_t read ( int fd, void *buf, size_t count);

size_t write ( int fd, const void * buf, size_t count);

参数: fd文件描述符;buf指向一段内存的指针;count想要读取或者写入fd的字节数。

返回值: 成功时返回实际读取或者写入fd的字节数;错误返回-1.

备注: 读取时如在到达文件尾还有30字节,而实际要求读100字节,则read返回30,下次调用read返回0;写入时 一般实际写入即第三个参数count字节 ,但由于磁盘空间限制或中断等原因,实际写入fd的字节数可能会count。在unix中,所有的设备都可以看成是一个文件,所以我们可以用read来读取socket数据。

recv、send

头文件: #include <sys/socket.h>

原型: ssize_t recv(int sockfd, void* buff, size_t nbytes, int flags);

ssize_t send(int sockfd, const void* buff, size_t nbytes, int flags);

参数: 前3个参数同read write的3个参数;flags要么是0要么是一些常值的逻辑或;常值及意义参阅头文件。

返回值: 成功返回读写字节数,错误返回-1.

功能: 比read write多了一个参数flags,可以理解为比read write操作更细化的函数,但仅用于套接字。

recvfrom、sendto

头文件: #include <sys/socket.h>

原型: ssize_t recvfrom(int sockfd, void* buff, size_t nbytes, int flags, struct sockaddr* from, socklent_t* addr_len);

ssize_t sendto(int sockfd, void* buff, size_t nbytes, int flags, struct sockaddr* to, socklen_t addrlen);

参数: 前三个参数通write read,flags置为0(后续讲解),from\to 存放对端地址结构,addrlen地址结构长度;

功能: recvfrom接收来自对端from的信息存于buff中;sendto发送信息buff到对端to。

备注:

(1)注意recvfrom最后一个参数是指向整数值的指针,sendto是一个整数值;很好理解,因为recvfrom的最后一个参数是调用recvfrom时返回的对端地址结构长度,只有是指针型,我们才能够方便地使用该长度变量。

一般这样使用:

socklen_t addr_len;

addr_len = sizeof(struct sockaddr_in);

recvfrom(sockfd,buff,sizeof(buff),0,(struct sockaddr *)&addr,&addr_len);

这样在调用玩recvfrom后可以使用返回的addr_len了,如果该参数不是指针型,我们就不能使用它了。

(2)对于UDP,recvfrom返回0是可以接受的;而TCP的read返回0则表示对端关闭连接。

(3)如果不关心对端的协议地址,可以将recvfrom的最后两个参数置为空指针。

(4)recvfrom和sendto都可以用于TCP,但通常不这么做。

readv、writev

头文件:#include <uio.h>

原型: ssize_t readv(int filedes, const struct iovec *iov, int iovcnt);

ssize_t writev(int filedes, const struct iovec *iov, int iovcnt);

参数: filedes要在其上读写的标识符,iov指向iovec结构数组的指针,iovcnt数组元素个数。

返回值: 成功返回读写字节数,错误返回-1.

功能: 分散读(scatter read),集中写(gather write)。

例子:

#include

int main(int argc,char **argv)

{

char part1[] = "This is iov";

char part2[] = " and ";

char part3[] = " writev test";

struct iovec iov[3];

iov[0].iov_base = part1;

iov[0].iov_len = strlen(part1);

iov[1].iov_base = part2;

iov[1].iov_len = strlen(part2);

iov[2].iov_base = part3;

iov[2].iov_len = strlen(part3);

writev(1,iov,3);

return 0;

}

recvmsg、sendmsg

头文件: #include <sys/socket.h>

原型: ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

ssize_t sendmsg(int sockfd, msghdr *msg, int flags);

参数: sockfd要对其读写的文件描述符,flags参阅头文件。

返回值: 成功返回读写字节数,出错返回-1.

功能: 通用的I/O函数,即可以把所有read、readv、recv、recvfrom换成recvmsg;可以把所有write、writev、send、sendto换成sendmsg.

备注: 那么是如何做到替换的呢?关键在msghdr结构体,如下,

struct msghdr {

void *msg_name;

socklen_t msg_namelen;

struct iovec *msg_iov;

size_t msg_iovlen;

void *msg_control;

socklen_t msg_controllen;

int msg_flags;

};

5组I/O函数比较汇总





一般在UDP套接字中使用recvfrom sendto;在TCP套接字中使用read write.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: