recv() - Unix,Linux系统调用
Tutorials Point


  Unix入门
  Unix Shell编程
  高级Unix
  Unix有用参考
  Unix有用资源
  精选阅读

版权所有 © 2014 tutorialspoint



  首页     参考     讨论论坛     关于TP  

recv() - Unix,Linux系统调用


previous next AddThis Social Bookmark Button

广告

名称

recv, recvfrom, recvmsg - 从套接字接收消息

概要

#include <sys/types.h> 

#include <sys/socket.h>

ssize_t recv(int s, void *buf, size_t len, int flags);

ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

ssize_t recvmsg(int s, struct msghdr *msg, int flags);

描述

recvfrom() 和 recvmsg() 调用用于从套接字接收消息,无论套接字是否面向连接,都可以使用它们来接收套接字上的数据。

如果from不为NULL,并且底层协议提供源地址,则填充此源地址。参数fromlen是一个值-结果参数,初始化为与from关联的缓冲区的size,并在返回时修改为指示实际存储在那里的地址大小。

recv() 调用通常仅用于已连接的套接字(参见connect(2)),并且与from参数为NULL的recvfrom()相同。

所有三个例程在成功完成时都返回消息的长度。如果消息太长而无法放入提供的缓冲区中,则可能会根据接收消息的套接字类型丢弃多余的字节。

如果套接字上没有可用消息,则接收调用将等待消息到达,除非套接字是非阻塞的(参见fcntl(2)),在这种情况下,将返回-1,并且外部变量errno设置为EAGAIN。接收调用通常返回任何可用的数据,直到请求的数量,而不是等待收到请求的全部数量。

可以使用select(2) 或 poll(2) 调用来确定何时到达更多数据。

recv() 调用的flags参数是通过对以下值之一或多个进行OR运算形成的

标签描述
MSG_DONTWAIT
 启用非阻塞操作;如果操作会阻塞,则返回EAGAIN(这也可以使用O_NONBLOCKF_SETFL fcntl(2)一起启用)。
MSG_ERRQUEUE
 此标志指定应从套接字错误队列接收排队的错误。错误通过辅助消息传递,其类型取决于协议(对于IPv4 IP_RECVERR)。用户应提供足够大小的缓冲区。有关更多信息,请参见cmsg(3) 和 ip(7)。导致错误的原始数据包的有效负载作为普通数据通过msg_iovec传递。导致错误的数据报的原始目标地址通过msg_name提供。
对于本地错误,不会传递地址(这可以使用cmsghdrcmsg_len成员进行检查)。对于错误接收,MSG_ERRQUEUEmsghdr中设置。传递错误后,将根据下一个排队的错误重新生成挂起的套接字错误,并在下一个套接字操作中传递。

错误在sock_extended_err结构中提供

#define SO_EE_ORIGIN_NONE 0 #define SO_EE_ORIGIN_LOCAL 1 #define SO_EE_ORIGIN_ICMP 2 #define SO_EE_ORIGIN_ICMP6 3

struct sock_extended_err { u_int32_t ee_errno; /* error number */ u_int8_t ee_origin; /* where the error originated */ u_int8_t ee_type; /* type */ u_int8_t ee_code; /* code */ u_int8_t ee_pad; u_int32_t ee_info; /* additional information */ u_int32_t ee_data; /* other data */ /* More data may follow */ };

struct sockaddr *SO_EE_OFFENDER(struct sock_extended_err *);

ee_errno包含排队错误的errno编号。ee_origin是错误源代码。其他字段是特定于协议的。宏SOCK_EE_OFFENDER返回指向网络对象的地址的指针,该网络对象是给定指向辅助消息的指针的错误来源。如果不知道此地址,则sockaddrsa_family成员包含AF_UNSPEC,并且sockaddr的其他字段未定义。导致错误的数据包的有效负载作为普通数据传递。
对于本地错误,不会传递地址(这可以使用cmsghdrcmsg_len成员进行检查)。对于错误接收,MSG_ERRQUEUEmsghdr中设置。传递错误后,将根据下一个排队的错误重新生成挂起的套接字错误,并在下一个套接字操作中传递。
MSG_OOB
 此标志请求接收带外数据,这些数据不会在普通数据流中接收。某些协议将快速数据放在普通数据队列的开头,因此此标志不能与这些协议一起使用。
MSG_PEEK
 此标志导致接收操作从接收队列的开头返回数据,而不会从队列中删除该数据。因此,后续的接收调用将返回相同的数据。
MSG_TRUNC
 返回数据包的真实长度,即使它比传递的缓冲区更长。仅对数据包套接字有效。
MSG_WAITALL
 此标志请求操作阻塞,直到完全满足请求。但是,如果捕获信号、发生错误或断开连接,或者要接收的下一个数据与返回的数据类型不同,则调用仍可能返回少于请求的数据。
recvmsg() 调用使用msghdr结构来最小化直接提供的参数的数量。此结构具有以下形式,如<sys/socket.h>中定义

struct msghdr { void *msg_name; /* optional address */ socklen_t msg_namelen; /* size of address */ struct iovec *msg_iov; /* scatter/gather array */ size_t msg_iovlen; /* # elements in msg_iov */ void *msg_control; /* ancillary data, see below */ socklen_t msg_controllen; /* ancillary data buffer len */ int msg_flags; /* flags on received message */ };

这里msg_namemsg_namelen指定套接字未连接时的源地址;如果不需要或不需要名称,则msg_name可以指定为null指针。字段msg_iovmsg_iovlen描述分散-聚集位置,如readv(2)中所述。字段msg_control(长度为msg_controllen)指向用于其他协议控制相关消息或其他辅助数据的缓冲区。调用recvmsg()时,msg_controllen应包含msg_control中可用缓冲区的长度;成功调用返回后,它将包含控制消息序列的长度。
消息的形式为

struct cmsghdr { socklen_t cmsg_len; /* data byte count, including hdr */ int cmsg_level; /* originating protocol */ int cmsg_type; /* protocol-specific type */ /* followed by u_char cmsg_data[]; */ };

辅助数据只能由cmsg(3)中定义的宏访问。
例如,Linux使用此辅助数据机制通过Unix套接字传递扩展错误、IP选项或文件描述符。
recvmsg()返回后,将设置msghdr中的msg_flags字段。它可以包含多个标志
MSG_EOR
 指示记录结束;返回的数据完成了一个记录(通常与类型为SOCK_SEQPACKET的套接字一起使用)。
MSG_TRUNC
 指示由于数据报大于提供的缓冲区而丢弃了数据报的尾部。
MSG_CTRUNC
 指示由于辅助数据缓冲区空间不足而丢弃了一些控制数据。
MSG_OOB
 返回以指示已接收快速数据或带外数据。
MSG_ERRQUEUE
 指示未接收数据,但来自套接字错误队列的扩展错误。

返回值

这些调用返回接收到的字节数,如果发生错误则返回-1。当对等体执行有序关闭时,返回值将为0。

错误

这些是由套接字层生成的一些标准错误。可能会生成并从底层协议模块返回其他错误;请参阅其手册页。
标签描述
EAGAIN 套接字被标记为非阻塞,并且接收操作会阻塞,或者已设置接收超时,并且在接收到数据之前超时已过期。
EBADF 参数s是无效的描述符。
ECONNREFUSED
 远程主机拒绝允许网络连接(通常是因为它没有运行请求的服务)。
EFAULT 接收缓冲区指针指向进程的地址空间之外。
EINTR 在任何数据可用之前,接收被信号传递中断。
EINVAL 传递无效参数。
ENOMEM 无法为recvmsg()分配内存。
ENOTCONN
 套接字与面向连接的协议关联,但尚未连接(参见connect(2) 和 accept(2))。
ENOTSOCK
 参数s不引用套接字。

符合标准

4.4BSD(这些函数调用首次出现在4.2BSD中),POSIX.1-2001。

POSIX.1-2001仅描述MSG_OOBMSG_PEEKMSG_WAITALL标志。

注释

上面给出的原型遵循glibc2。Single Unix Specification一致,除了它具有类型为“ssize_t”的返回值(而4.x BSD和libc4和libc5都具有“int”)。flags参数在4.x BSD中为“int”,但在libc4和libc5中为“unsigned int”。len参数在4.x BSD中为“int”,但在libc4和libc5中为“size_t”。fromlen参数在4.x BSD、libc4和libc5中为“int *”。目前的“socklen_t *”是由POSIX发明的。另见accept(2)。

根据POSIX.1-2001,msghdr结构的msg_controllen字段应类型化为socklen_t,但glibc当前(2.4)将其类型化为size_t

参见



previous next Printer Friendly

广告


  

广告



广告