recv,recvfrom,recvmsg函数用于从套接字接收信息。
ssize_t recv (int s, void *buf, size_t len, int flags);

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

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

recvfrom和recvmsg系统调用用于从套接字接收消息,也可以用来接受套接字数据,不管其是否是面向连接的。 recv函数通常用于面向连接的套接字(参看[[[Open C 套接字: connect 方法|connect]]),等同于用空指针传入from参数时

的recvfrom。所有三个例程都返回成功时的消息长度。

recvmsg系统调用使用msghdr结构将直接提供的参数个数减到最少,这个结构具有以下格式,定义在sys/socket.h文件:
struct msghdr {
caddr_t msg_name; /* optional address */
u_int msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
u_int msg_iovlen; /* # elements in msg_iov */
caddr_t msg_control; /* ancillary data, see below */
u_int msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};

下面的代码片段演示了recv, recvfrom, recvmsg函数的用法:
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
void Recv()
{
struct sockaddr_in serv_addr;
int sock_fd;
char line[10];
int size = 10;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
serv_addr.sin_port = htons(5000);
sock_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
connect(sock_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
recv(sock_fd, line, size, 0);
close(sock_fd);
}

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
void Sendto()
{
struct sockaddr_in sender_addr;
int sock_fd;
char line[15] = "Hello World!";
unsigned int size = sizeof(sender_addr);
sock_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
sender_addr.sin_family = AF_INET;
sender_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sender_addr.sin_port = htons(5000);
recvfrom(sock_fd,line,13,0,(struct sockaddr*)&sender_addr,&size);
close(sock_fd);
}

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
void SendMsgRecvMsg()
{
int sock_fd;
unsigned int sender_len;
struct msghdr msg;
struct iovec iov;
struct sockaddr_in receiver_addr,sender_addr;
char line[10];
sock_fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
receiver_addr.sin_family = AF_INET;
receiver_addr.sin_addr.s_addr = htonl(INADDR_ANY);
receiver_addr.sin_port = htons(5000);
bind(sock_fd,(struct sockaddr*)&receiver_addr,sizeof(receiver_addr));
sender_len = sizeof(sender_addr);
msg.msg_name = &sender_addr;
msg.msg_namelen = sender_len;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_iov->iov_base = line;
msg.msg_iov->iov_len = 10;
msg.msg_control = 0;
msg.msg_controllen = 0;
msg.msg_flags = 0;
recvmsg(sock_fd,&msg,0);
close(sock_fd);
}

这些调用返回接收的字节数,或者如错误发生返回-1。

==========================================================================================
【recv/recvfrom/recvmsg系统调用】
功能描述:
从套接字上接收一个消息。对于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索引的不是套接字

转载于:https://www.cnblogs.com/hnrainll/archive/2011/08/16/2141480.html

recv, recvfrom, recvmsg相关推荐

  1. Linux系统调用-- recv/recvfrom/recvmsg函数详解(转)

    Linux系统调用-- recv/recvfrom/recvmsg函数详解 2007-09-10 23:37 [recv/recvfrom/recvmsg系统调用]   功能描述: 从套接字上接收一个 ...

  2. linux中recvfrom读取速度,Linux系统调用-- recv/recvfrom 函数详解

    Linux系统调用-- recv/recvfrom函数详解 功能描述: 从套接字上接收一个消息.对于recvfrom,可同时应用于面向连接的和无连接的套接字.recv一般只用在面向连接的套接字,几乎等 ...

  3. linux内核 recvfrom,Linux系统调用-- recv/recvfrom 函数详解

    Linux系统调用-- recv/recvfrom函数详解 功能描述: 从套接字上接收一个消息.对于recvfrom,可同时应用于面向连接的和无连接的套接字.recv一般只用在面向连接的套接字,几乎等 ...

  4. send/sendto和recv/recvfrom各自的区别

    一般情况下:    send(),recv()用于TCP,sendto()及recvfrom()用于UDP    但是send(),recv()也可以用于UDP,sendto()及recvfrom() ...

  5. send sendto ,recv recvfrom有什么区别

    一般情况下: send(),recv()用于TCP,sendto()及recvfrom()用于UDP 但是send(),recv()也可以用于UDP,sendto()及recvfrom()也可以用于T ...

  6. TCP通信常用的send,sendto,recv,recvfrom函数详解

    send函数 int send( SOCKET s,    const char FAR *buf,    int len,    int flags ); 不论是客户还是服务器应用程序都用send函 ...

  7. linux recv返回值,recv recvfrom

    recv和recvfrom都是用来接受来自的网络的数据.来看看它们的原型: int recv( SOCKET, char FAR*, int, int ); int recvfrom( SOCKET, ...

  8. recv recvfrom 区别

    recv的recvfrom是可以替换使用的,只是recvfrom多了两个参数,可以用来接收对端的地址信息,这个对于udp这种无连接的,可以很方便地进行回复.而换过来如果你在udp当中也使用recv,那 ...

  9. 条件变量 pthread_cond_wait

    1.先了解一下等待队列.(默认大家了解mutex,如果不了解:https://blog.csdn.net/qq_33890670/article/details/79967231) 等待队列,是指li ...

最新文章

  1. springboot日志logback配置
  2. nginx收到空包问题
  3. hive获取月份_【Hive】Hive中常用日期函数整理
  4. jdk8 字符串_在JDK 8中连接字符串
  5. DynamipsGUI下CISCO SDM的安装配置
  6. LeetCode 1824. 最少侧跳次数(DP)
  7. netbsd配置gnome桌面
  8. L2-DAY 2-程序完善夜
  9. Android 系统(49)---Android获取窗口可视区域大小: getWindowVisibleDisplayFrame()
  10. C语言学习笔记---枚举类型enum
  11. P3047 [USACO12FEB]附近的牛Nearby Cows
  12. 西威变频器avo下载调试资料_变频器设置面板及参数设置方法
  13. 扑克牌java发牌_Java实现扑克牌洗牌和发牌
  14. iOS通过URL Scheme启动app(收集了常用的app的URL Scheme)
  15. 计算机研究生复试面试题目
  16. mysql week weekofyear_MySQL WEEKOFYEAR()用法及代码示例
  17. SpringBoot官方开发工具,热部署和远程调试真带劲
  18. 探索 Zynq MPSoC:配套 PYNQ 和机器学习应用一起使用 - 序言鸣谢目录20211231
  19. python计算召回率_机器学习之分类:精确率和召回率
  20. .set_global_opts(title_opts) 设置标题

热门文章

  1. 信号与系统 chapter6 时变与时不变系统
  2. socketserver和socket的补充(验证客户端合法性)
  3. Nginx 怎么给一台服务器,配置两个域名?详细的解说+截图教程
  4. TCP Congestion Control
  5. 从去除毛刺的策略看开运算opening_circle和闭运算closing_circle的异同
  6. 神州泰岳2050万元收买并增资奇点国际
  7. nginx是干嘛用的_nginx小技巧 -非root身份运行nginx
  8. 如何取消 登录_LSAT | 退考、缺考、取消成绩,各自的区别和流程是怎样的?
  9. java md2_java中加密的实现方法(MD5,MD2,SHA)
  10. 怎样用u盘linux安装ntp协议,电脑中怎么配置NTP服务