功能描述: 
从套接字上接收一个消息。对于recvfrom 和 recvmsg,可同时应用于面向连接的和无连接的套接字。recv一般只用在面向连接的套接字,几乎等同于recvfrom,只要将recvfrom的第五个参数设置NULL。
如果消息太大,无法完整存放在所提供的缓冲区,根据不同的套接字,多余的字节会丢弃。
假如套接字上没有消息可以读取,除了套接字已被设置为非阻塞模式,否则接收调用会等待消息的到来。

用法:  

 #include <sys/types.h> 

 #include <sys/socket.h> 

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

 ssize_t recvfrom(int sock, void *buf, size_t len, int flags,  

      struct sockaddr *from, socklen_t *fromlen); 

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

 参数:    

 sock:索引将要从其接收数据的套接字。 

 buf:存放消息接收后的缓冲区。 

 len:buf所指缓冲区的容量。 

 flags:是以下一个或者多个标志的组合体,可通过or操作连在一起 

 MSG_DONTWAIT:操作不会被阻塞。 

 MSG_ERRQUEUE: 指示应该从套接字的错误队列上接收错误值,依据不同的协议,错误值以某种辅佐性消息的方式传递进来, 使用者应该提供足够大的缓冲区。导致错误的原封包通过msg_iovec作为一般的数据来传递。导致错误的数据报原目标地址作为msg_name被提供。 错误以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 */ 

 }; 

 MSG_PEEK:指示数据接收后,在接收队列中保留原数据,不将其删除,随后的读操作还可以接收相同的数据。 

 MSG_TRUNC:返回封包的实际长度,即使它比所提供的缓冲区更长, 只对packet套接字有效。  

 MSG_WAITALL:要求阻塞操作,直到请求得到完整的满足。然而,如果捕捉到信号,错误或者连接断开发生,或者下次被接收的数据类型不同,仍会返回少于请求量的数据。 

 MSG_EOR:指示记录的结束,返回的数据完成一个记录。 

 MSG_TRUNC:指明数据报尾部数据已被丢弃,因为它比所提供的缓冲区需要更多的空间。 

 MSG_CTRUNC:指明由于缓冲区空间不足,一些控制数据已被丢弃。 

 MSG_OOB:指示接收到out-of-band数据(即需要优先处理的数据)。 

 MSG_ERRQUEUE:指示除了来自套接字错误队列的错误外,没有接收到其它数据。 

 from:指向存放对端地址的区域,如果为NULL,不储存对端地址。 

 fromlen:作为入口参数,指向存放表示from最大容量的内存单元。作为出口参数,指向存放表示from实际长度的内存单元。 

 msg:指向存放进入消息头的内存缓冲,结构形态如下 

 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 */ 

 }; 



 可能用到的数据结构有 

 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[]; */ 

 }; 



 返回说明:    

 成功执行时,返回接收到的字节数。另一端已关闭则返回0。失败返回-1,errno被设为以下的某个值    

 EAGAIN:套接字已标记为非阻塞,而接收操作被阻塞或者接收超时 

 EBADF:sock不是有效的描述词 

 ECONNREFUSE:远程主机阻绝网络连接 

 EFAULT:内存空间访问出错 

 EINTR:操作被信号中断 

 EINVAL:参数无效 

 ENOMEM:内存不足 

 ENOTCONN:与面向连接关联的套接字尚未被连接上 

 ENOTSOCK:sock索引的不是套接字