一、格式
#include<sys/types.h>
#include<sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t nbytes, int flags,
struct sockaddr *from, socklen_t *addrlen);
ssize_t sendto(int sockfd, const void *buf, size_t nbytes, int flags,
const struct sockaddr *to, socklen_t addrlen);
参数
recvfrom返回值
- 成功:返回接收到的字节数
- 返回0:
- 当一个流套接字对等节点有序地关闭时,返回值将为0(传统的“end-of-file”标志)
- 不同域(例如UNIX和Internet域)中的数据报套接字允许零长度的数据报。当接收到这样的数据报时,返回值为0。
- 如果要从流套接字接收的请求字节数为0,也可以返回值0
- 失败:返回-1,并将errno设置为如下的值:
- 这些是套接字层生成的一些标准错误。底层协议模块可能会产生和返回其他错误
- EAGAIN或EWOULDBLOCK:套接字标记为非阻塞,接收操作将阻塞,或者设置了接收超时,并且在接收数据之前超时已经过期。在这种情况下,POSIX.1允许返回任何一个错误,并且不要求这些常量具有相同的值,因此可移植应用程序应该检查这两种可能性
- EBADF:参数sockfd是一个无效的文件描述符
- ECONNREFUSED:远程主机拒绝允许网络连接(通常是因为它没有运行所请求的服务)
- EFAULT:将接收缓冲区指针指向进程地址空间之外
- EINTR :在任何数据可用之前,接收被信号的发送打断
- EINVAL:无效参数传递
- ENOMEM:无法为recvmsg()分配内存
- ENOTCONN:套接字与一个面向连接的协议相关联,并且还没有被连接(参阅connect()和accept())
- ENOTSOCK:文件描述符sockfd不引用套接字
sendto返回值
- 成功:返回发送的字节数
- 失败:返回-1,并将errno设置为如下的值:
- 这些是套接字层产生的一些标准错误。底层协议模块可能会产生和返回其他错误
- EACCES:
- 在目标套接字文件上拒绝EACCES(对于UNIX域套接字,它是由路径名标识的)的写权限,或者拒绝路径前缀中的某个目录的搜索权限。(参阅path_resolution())。
- (对于UDP套接字)尝试发送到网络/广播地址,就好像它是一个单播地址
- EAGAIN或EWOULDBLOCK:套接字标记为非阻塞,请求的操作将阻塞。在这种情况下,POSIX.1-2001允许返回任何一个错误,并且不要求这些常量具有相同的值,因此可移植应用程序应该检查这两种可能性
- EAGAIN:sockfd引用的套接字以前没有绑定到一个地址,当尝试将其绑定到临时端口时,确定临时端口范围内的所有端口号目前都在使用。参见ip(7)中的/proc/sys/net/ipv4/ip_local_port_range的讨论
- EALREADY:另一个快速开放正在进行中
- EBADF:sockfd不是一个有效的打开文件描述符
- ECONNRESET:通过对等点重置连接
- EDESTADDRREQ:套接字不是连接模式,没有设置对等地址
- EFAULT:为参数指定了无效的用户空间地址
- EINTR:在任何数据传输之前发生的信号
- EINVAL:无效参数传递
- EISCONN:连接模式套接字已经连接,但是指定了一个接收方。(现在要么返回此错误,要么忽略收件人规范。)
- EMSGSIZE:套接字类型要求以原子方式发送消息,而要发送的消息的大小使得这种情况不可能发生
- ENOBUFS:网络接口的输出队列已满。这通常表示接口已停止发送,但可能是由瞬态拥塞引起的。(通常,这在Linux中不会发生。当设备队列溢出时,数据包会无声地丢弃。)
- ENOMEM:没有可用的内存
- ENOTCONN:套接字没有连接,并且没有给定目标
- ENOTSOCK:文件描述符sockfd不引用套接字
- EOPNOTSUPP:标志参数中的一些位不适合套接字类型
- EPIPE:在一个面向连接的套接字上,本地端已经关闭。在本例中,除非设置了MSG_NOSIGNAL,否则进程还将收到一个SIGPIPE
注意事项
- 最后一个参数recvfrom函数为地址大小指针,sendto函数为地址大小
- 如果recvfrom的from参数是一个空指针,那么相应的长度参数(addrlen)也必须是一个空指针,表示我们并不关心数据发送者的协议地址
二、注意事项
- ①写一个长度为0的数据报是可行的。在UDP情况下,这会形成一个只包含一个IP首部(对于 IPv4通常为20个字节,对于IPv6通常为40个字节)和一个8字节UDP首部而没有数据的IP数据报。 这也意味着对于数据报协议,recvfrom返回0值是可接受的:它并不像TCP套接字上read返回0 值那样表示对端已关闭连接。既然UDP是无连接的,因此也就没有诸如关闭一个UDP连接之类事情
- ②recvfrom和sendto都可以用于TCP,尽管通常没有理由这样做