说明:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
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中 |
注意 |