c++ - 在 Linux 中,recv() 有效,但 recvmsg() 无效
问题描述
我在一个函数中有这个代码,在树莓派上运行:
struct sockaddr_in addr_buffer;
struct cmsghdr control_buffer;
struct msghdr msghdr;
struct iovec iov[1];
char msg_buffer[1458];
memset(&msg_buffer, 0, sizeof(msg_buffer));
memset(iov, 0, sizeof(iov));
memset(&msghdr, 0, sizeof(msghdr));
iov[0].iov_base = msg_buffer;
iov[0].iov_len = sizeof(msg_buffer);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msghdr.msg_name = &addr_buffer;
msghdr.msg_namelen = sizeof(addr_buffer);
msghdr.msg_control = &control_buffer;
msghdr.msg_controllen = sizeof(control_buffer);
msghdr.msg_flags = 0;
//int msgsize = recv(udpsocket_fd, &msg_buffer, 4, 0);
int msgs_received = recvmsg(udpsocket_fd, &msghdr, 0);
根据我所阅读的内容,recvmsg() 系统调用应该一次返回到 msghdr 指向的 iovec 一条消息(因为 iovec 数组的长度为 1 个单位)。但是,它不起作用:我正确接收了标头,因为我可以使用调试器读取哪个 IP 已发送数据包,但 msg_buffer 仍然为空。该函数还返回 0,这很奇怪,因为这意味着没有发生错误(这将返回 -1),但也意味着没有收到任何消息(尽管标头已更新)
但是,如果我取消注释 recv() 行,一切都会按预期工作,并且消息在 msg_buffer 中。但是,很明显,没有收到额外的信息。我已经挠头两个小时了,看不出代码有什么问题。非常感谢您的帮助!
解决方案
从您所显示的内容来看,您只是不正确地初始化msghdr
。尝试在recvmsg
通话前添加:
mhdr.msg_iov = iov;
mhdr.msg_iovlen = 1;
推荐阅读
- python - 如何将日期信息附加到 read_csv 上的时间列
- rdkit - 如何在rdkit中质子化一个分子?
- javascript - 循环遍历 javascript 对象而不基于键进行排序
- java - 如何使用 Java 接口比较器进行通用合并排序?
- kubernetes - Kubernetes 滚动更新:在更新之前尊重 pod 的准备情况
- javascript - 将字符集放在 JavaScript 文件中不起作用
- asp.net-core - 为了响应在没有足够权限的情况下删除资源的请求,在休息 API 中引发的正确异常是什么?
- data-structures - 为什么我需要堆栈和队列?
- azure - 部署 Azure Web 作业
- react-native - “react-native init”模板应用程序的问题:无法从 react-native/scripts 解析模块`./index`