函数简介篇——常用IO函数

说明
  本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
  QQ 群 号:513683159 【相互学习】
内容来源
  《Linux网络编程》、《Unix环境高级编程》

IO函数的比较

  read()/write()、readv()/writev()可对所有文件描述符使用。
  recv()/send()、recvfrom()/writeto()、recvmsg()/sendmsg()只能操作套接字描述符。
  readv()/writev()、recvmsg()/sendmsg()可操作多个缓冲区
  read()/write()、recv()/send()、recvfrom()/sendto()只能操作单个缓冲区
  recv()/send()、recvfrom()/sendto()、recvmsg()/sendmsg()具有可选标志
  recvfrom()/sendto()、recvmsg()/sendmsg()可选择对方的IP地址
  recvmsg()/sendmsg()可选择的控制信息,能进行高级操作。
  表9.8为函数使用时的特点,○标记的为具有此种属性:
在这里插入图片描述

read()函数——从文件描述符读取

  1.函数功能:从文件描述符fd读取count字节数到缓冲区buf中。
    对于支持查找的文件,读取操作从文件偏移量开始,文件偏移量随读取字节数的增加而增加。如果文件偏移量位于或超过文件的末尾,则不读取字节,read()返回零。

项目 说明
函数原型 ssize_t read(int fd, void *buf, size_t count);
头文件 unistd.h
参数说明 1.fd:文件描述符:
指向已打开文件的句柄
2.buf:缓冲区:
指向一块用于存储的内存区域
3.count:字节数:
调用一次read操作,应该读取的字节字符个数
返回值 返回实际上读取的字符数量,错误为-1,EOF为0。
注意 ①EOF = end of file,此处用来表达到达文件末尾
write()函数——写入文件描述符

  1.函数功能:从缓冲区buf开始向上写入count字节数到文件描述符fd所引用的文件。
    若底层物理介质上的空间不足,或者遇到了RLIMIT_FSIZE资源限制(参见setrlimit(2)),或者在写入的字节数小于count字节后,调用被信号处理器中断,则写入的字节数可能小于count.
    对于一个可搜索的文件(例如,一个可以应用lseek(2)的文件,例如一个普通的文件),在文件偏移量处进行写入,并且文件偏移量增加实际写入的字节数。若文件是用O_APPEND(2)打开的,那么在写入之前,文件的偏移量首先设置为文件的末尾。文件偏移量的调整和写操作是作为原子步骤执行的。

项目 说明
函数原型 ssize_t write(int fd, const void *buf, size_t count);
头文件 unistd.h
参数说明 1.fd:文件描述符:
指向已打开文件的句柄
2.buf:缓冲区:
指向一块存有内容的内存区域
3.count:字节数:
调用一次write操作,应该写入的字节字符个数
返回值 返回实际所写入的字节数,错误返回-1,错误代码存入errno中。
注意 ①EINTR 此调用被信号所中断.
②EAGAIN 当使用不可阻断I/O 时 (O_NONBLOCK), 若无数据可读取则返回此值.
③EADF 参数fd 非有效的文件描述词, 或该文件已关闭.
readv()函数——将数据读到多个缓冲区

  1.函数功能
    从与文件描述符fd相关的文件中读取iovcnt块缓冲区到iov(“分散输入”)所描述的中。
    readv()系统调用的工作方式与read(2)类似,不同的是多个缓冲区被填满。

项目 说明
函数原型 ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
头文件 sys/uio.h
参数说明 1.fd,:套接字文件描述符
2.iov:指向向量的指针(结构在struct_iovec.h中定义):
指向一块结构为vector的内存。
3.iovcnt:块数(内存大小)
返回值 成功返回接收到的字节数,错误返回-1,错误代码存入errno中
注意 ①readv()函数时必须指定iovec的iov_base长度,将值放到成员iov_len中。
②缓冲区按数组顺序处理。这意味着readv()在继续到iov[1]之前完全填充了iov[0],以此类推。(如果数据不足,则iov指向的所有缓冲区可能都被填满。)
③数据传输是原子的,保证从文件中读取连续的数据块,而不管其他线程或进程中执行的读取操作,这些线程或进程的文件描述符引用了相同的打开文件描述符(参见open(2))。

  2.iovec结构的数组

//位置:struct_iovec.h
/* 分散/聚集I/O的结构  */
struct iovec
{
    void *iov_base;	 /* 数据的指针:向量缓冲区起始地址 */
    size_t iov_len;	 /* 数据的长度:向量缓冲区的大小,以字节为单位 */
};

在这里插入图片描述

  3.errno值
在这里插入图片描述

writev()函数——将数据写到多个缓冲区

  1.函数功能
    将iov描述的iovcnt缓冲区写入与文件描述符fd相关的文件(“收集输出”)。
    writev()系统调用的工作方式与write(2)类似,只是写入了多个缓冲区。

项目 说明
函数原型 ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
头文件 sys/uio.h
参数说明 1.fd:套接字文件描述符
2.iov:指向向量的指针(结构在struct_iovec.h中定义):
指向一块结构为vector的内存。
3.iovcnt:块数(内存大小)
返回值 成功返回发送的字节数,错误返回-1,错误代码存入errno中
注意 ①缓冲区按数组顺序处理。writev()在进行iov[1]之前会将iov[0]的全部内容写出来,以此类推。
②数据传输是原子的:writev()写入的数据作为一个单独的块写入,不会与其他进程的写输出混合在一起(但见pipe(7)的异常)

  2.errno值

recv()函数

  函数功能:用于接收数据。
    从套接字FD接收N个字节的数据到缓冲区BUF,操作方式由flag指定。

项目 说明
函数原型 extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags);
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字文件描述符:
指定接收端的套接字文件描述符
2.__buf:缓冲区
指向用来存放接收到数据的区域
3.__n:缓冲区长度
指明接收缓冲区的长度
4.__flags:标记变量
设置接收数据方式,一般置为0
返回值 成功返回接收到的字节数,错误返回-1,错误代码存入errno中
注意 ①常用于TCP类型的套接字,UDP使用recvfrom()函数接收数据
(在数据报套接字绑定地址和端口后,也可使用recv函数接收数据)
②从内核的接收缓冲区中复制数据到用户指定的缓冲区,
若内核数据比缓冲区小时,会复制缓冲区所有内容并返回数据长度。
若内核数据比缓冲区多时,其余数据需下次调用接收函数再复制(会调回复制过的数据)。

在这里插入图片描述
在这里插入图片描述

send()函数

  函数功能:用于发送数据。
    通过设置flag以指定的方式,将缓冲区(BUF)中N字节数据发送到套接字FD。

项目 说明
函数原型 extern ssize_t send (int __fd, const void *__buf, size_t __n, int __flags);
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字文件描述符
指向已建立好连接的套接字文件描述符
2.__buf:缓冲区
指向想要发送数据的缓冲区
3.__n:缓冲区长度
指明发送缓冲区的长度
4._flags:标记变量
设置接收数据方式,一般置为0
返回值 成功返回发送出去的字符个数,失败返回-1,错误代码存入errno中。
注意 ①发送数据时不一定全部发送出去,故需检查返回值
若返回值小于缓冲区长度时,需将剩余数据发送,要对原来buf中数据位置进行偏移,偏移大小为已发送成功的字节数。
②只能用于处于连接状态的套接字描述符
③flag=0时,send()函数与writee()函数完全一致
④send(s,buf,len,flags)与sendto(s,buf,len,flags,NULL,0)等价

在这里插入图片描述

recvmsg()函数

  函数功能:用于接收数据。(与recv()函数、readv()函数相比较,此函数使用更复杂)
    以flag操作方式,从套接字FD接收message描述的消息。

项目 说明
函数原型 extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags);
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字文件描述符
2.__message:消息结构体
3.__flags:标记变量
设置操作方式
返回值 成功返回接受到的字节数,失败返回-1,错误代码存入errno中
注意
//位置:bits/socket.h
/* 该结构体描述由' sendmsg'发送和由' recvmsg'接收的消息  */
struct msghdr
  {
    void *msg_name;		     /* 发送/接收的地址  */
    socklen_t msg_namelen;   /* 地址数据长度  */

    struct iovec *msg_iov;	 /* 发送/接收到的数据向量  */
    size_t msg_iovlen;		 /* 向量中元素的个数  */

    void *msg_control;		/* 辅助数据(例如BSD文件传递) */
    size_t msg_controllen;	/* 辅助数据缓冲区长度。! !类型应该是socklen_t,但是内核的定义与此不兼容 */

    int msg_flags;		    /* 接收消息的标记  */
  };

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

sendmsg()函数

  函数功能:用于发送数据
    以flag操作方式,在socket FD上发送一个描述message的消息。

项目 说明
函数原型 extern ssize_t sendmsg (int __fd, const struct msghdr *__message,int __flags);
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字文件描述符
2.__message:消息结构体
3.__flags:标记变量
设置操作方式
返回值 成功返回发送的字节数,失败返回-1,错误代码存入errno中
注意
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值