当前位置: 首页 > news >正文

recvmsg函数的用法

recvmsg 是 Linux 网络编程中用于接收消息的高级系统调用,支持复杂数据结构和辅助数据的接收,适用于 TCP/UDP/UNIX 域套接字等场景‌。以下是其核心用法详解:


1. 函数原型与参数

#include <sys/socket.h>
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
  • sockfd
    套接字描述符,需预先通过 socket() 创建‌。
  • msg
    指向 msghdr 结构体的指针,用于存储消息的元数据和缓冲区信息(见下文详细解析)‌。
  • flags
    控制接收行为的标志位(如 MSG_PEEK 预览数据、MSG_WAITALL 阻塞直到数据满缓冲区)‌。

2. msghdr 结构体详解

struct msghdr {void         *msg_name;       // 可选:发送方地址(UDP 适用)socklen_t     msg_namelen;    // 地址长度struct iovec *msg_iov;        // 分散/聚集 I/O 缓冲区数组size_t        msg_iovlen;     // 缓冲区数量void         *msg_control;    // 辅助数据(如文件描述符)size_t        msg_controllen; // 辅助数据长度int           msg_flags;      // 接收消息的标志(输出参数)
};
关键字段说明
  • msg_iov 与 msg_iovlen
    支持多缓冲区接收数据(分散读取),通过 iovec 结构体数组实现:
    struct iovec {void  *iov_base;  // 缓冲区起始地址size_t iov_len;   // 缓冲区长度
    };
    
    示例:同时接收数据到 buf1 和 buf2‌。
  • msg_control 与 msg_controllen
    用于接收辅助数据(如 UNIX 域套接字传递的文件描述符),需配合 cmsghdr 结构体解析‌。

3. 典型应用场景

场景1:UDP 接收数据(带发送方地址)
struct sockaddr_in sender_addr;
struct msghdr msg = {0};
struct iovec iov;
char buf[1024];iov.iov_base = buf;
iov.iov_len = sizeof(buf);
msg.msg_name = &sender_addr;
msg.msg_namelen = sizeof(sender_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;recvmsg(sockfd, &msg, 0);  // 接收数据并获取发送方地址‌:ml-citation{ref="3,5" data="citationList"}
场景2:接收文件描述符(UNIX 域套接字)
struct msghdr msg = {0};
struct iovec iov;
char buf‌[8192];
int fd;  // 接收的文件描述符// 辅助数据缓冲区(需对齐)
union {struct cmsghdr cm;char control[CMSG_SPACE(sizeof(int))];
} control_un;iov.iov_base = buf;
iov.iov_len = sizeof(buf);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);recvmsg(sockfd, &msg, 0);// 解析辅助数据获取文件描述符
struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg);
if (cmptr != NULL && cmptr->cmsg_type == SCM_RIGHTS) {fd = *((int *)CMSG_DATA(cmptr));  // 提取描述符‌
}

4. 标志位(flags)详解

标志作用
MSG_PEEK预览数据但不从接收缓冲区移除(可重复读取)‌
MSG_WAITALL阻塞直到请求的字节数全部接收(TCP 适用)‌
MSG_DONTWAIT非阻塞模式,无数据时立即返回 EAGAIN
MSG_TRUNC若数据被截断,通过 msg_flags 返回该标志(UDP 适用)‌

5. 错误处理

  • 返回值
    成功时返回接收的字节数,失败返回 -1 并设置 errno(如 EAGAINECONNRESET)‌。
  • msg_flags 输出
    接收后可通过 msg.msg_flags 检查附加标志(如 MSG_TRUNCMSG_CTRUNC)‌。

6. 性能与扩展性

  • 优势
    相比 recv/recvfromrecvmsg 支持多缓冲区和辅助数据,减少系统调用次数,提升效率‌。
  • 限制
    复杂参数需谨慎处理,如 msg_control 缓冲区未对齐可能导致错误‌。

此函数广泛应用于高级网络编程(如 SCTP 协议、容器通信)和进程间文件描述符传递‌。

http://www.dtcms.com/a/292505.html

相关文章:

  • 算法学习--滑动窗口
  • 学习python中离线安装pip及下载package的方法
  • C语言:函数基础
  • day059-zabbix自定义监控与自动发现
  • Node.js:Web模块、Express框架
  • es6中的symbol基础知识
  • 在Android开发中,如何获取到手机设备的PIN码?
  • 如何安装CMake较新的版本
  • Apache Ignite 长事务终止机制
  • 精密全波整流电路(一)
  • torchvision.transforms 与 MONAI 数据增强的异同
  • Cloud 与 VPS 的区别:如何选择最适合你的服务器解决方案?
  • stream流入门
  • 【打怪升级 - 01】保姆级机器视觉入门指南:硬件选型 + CUDA/cuDNN/Miniconda/PyTorch 安装全流程(附版本匹配秘籍)
  • vmware 克隆虚拟机,报错:克隆时出错:指定不存在的设备。然后电脑卡死,只能强制关机再开机。
  • FastDFS 6.11.0 单机环境搭建与测试(附 Nginx 集成)+ docker构建+k8s启动文件
  • 用org.apache.pdfbox 转换 PDF 到 图片格式
  • KafkaMQ 日志采集最佳实践
  • Python 正则表达式:入门到实战
  • 日常随笔-React摘要
  • 【ROS/DDS】FastDDS :编写FastDDS程序实现与ROS2 通讯(四)
  • 深入浅出理解 TCP 与 UDP:网络传输协议的核心差异与应用
  • 平台端用户管理功能设计全解:从分类管控到审核闭环
  • 基于springboot的疫苗发布和接种预约系统(论文+开题报告)
  • 实现分布式锁
  • 腾讯云SDK
  • 论文笔记:Parameter Competition Balancing for Model Merging
  • MongoDB频繁掉线频繁断开服务的核心原因以及解决方案-卓伊凡|贝贝|莉莉|糖果
  • 在Windows 10/11上使用Qt和SOEM构建EtherCAT主站:工业控制新纪元
  • 【Axure视频教程】形状地图