Unix套接字高级IO函数
下面将介绍recv、send、recvfrom以及sendto函数。
recv函数
#include<sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);
recv函数的作用类似于标准IO库中的read函数,不过需要多加一个额外的参数。
参数说明:
- sockfd:指定接收端套接字文件描述符
- buf:指定接收缓冲区的指针
- nbytes:指定接收数据的大小
- flags:标志位,有下列选项:
宏 | 说明 |
---|---|
MSG_DONTWAIT | 非阻塞,立即返回 |
MSG_OOB | 指明即将读入的是带外数据而不是普通数据 |
MSG_PEEK | 允许我们查看已可读取的数据,且系统不在recv返回后丢弃这些数据 |
MSG_WAITALL | 告知内核不要在尚未读入请求数目的字节之前让一个读操作返回 |
返回值说明:
返回值 | 说明 |
---|---|
<0 | 出错 |
=0 | 连接关闭 |
>0 | 接收到数据的大小 |
send函数
#include<sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);
recv函数的作用类似于标准IO库中的write函数。
参数说明:
- sockfd:指定发送端套接字文件描述符
- buf:指定发送缓冲区的指针
- nbytes:指定发送数据的大小
- flags:标志位,有下列选项:
宏 | 说明 |
---|---|
MSG_DONTROUTE | 告知内核目的主机在某个连接的本地网络中,因而无需执行路由查找 |
MSG_DONTWAIT | 非阻塞,立即返回 |
MSG_OOB | 指明即将读入的是带外数据而不是普通数据 |
返回值说明:
返回值 | 说明 |
---|---|
<0 | 出错 |
>=0 | 实际发送的数据大小 |
recvfrom函数
#include<sys/socket.h>
ssize_t recvfrom(int sokcfd, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);
recvfrom函数作用类似于标准IO函数read,不过需要三个额外参数。
参数说明:
- sockfd:指定接收的文件描述符
- buff:指定接收缓冲区指针
- nbytes:指定接收数据的大小,一般设置为缓冲区大小
- flags:同recv函数,使用UDP协议时一般设置为0
- from:指向数据报发送者的协议地址的套接字地址结构
- addrlen:数据报发送者套接字结构中填写的字节数
返回值:
返回值 | 说明 |
---|---|
>=0 | 读取的数据长度 |
<0 | 读取出错 |
sendto函数
#include<sys/socket.h>
ssize_t sendto(int sockfd, const void *buff, size_t nbytes, int flags, const struct sockaddr *to, socklen_t *addrlen);
sendto函数作用类似于标准IO函数send,需要三个额外的参数。
参数说明:
- sockfd:指定发送的套接字文件描述符
- buff:指定发送的数据缓冲区
- nbytes:指定要发送的数据大小
- flags:同send函数,使用UDP协议时一般设置为0
- to:指向数据包接收者的协议地址的套接字地址结构
- addrlen:指定接收者套接字地址结构的大小
返回值:
返回值 | 说明 |
---|---|
>=0 | 写入的数据大小 |
<0 | 写入出错 |
errno出错码
recv、send、recvfrom以及sendto函数返回-1时,表明出现了某些错误。此时errno会被置为以下某个值:
宏 | 说明 |
---|---|
EAGAIN | 套接字已标志位非阻塞 |
EBADF | sock不是有效的描述符 |
ECONNREFUSE | 远程主机拒绝网络连接 |
EFAULT | 内存空间访问出错 |
EINTR | 操作被信号中断 |
EINVAL | 参数无效 |
ENOMEM | 内存不足 |
ENOTCONN | 与面向连接关联的套接字尚未连接上 |
ENOTSOCK | sock索引的不是套接字 |
参考书籍:《Unix网络编程卷1:套接字联网API(第三版)》