gpt4 book ai didi

linux - 苹果操作系统 X : recvmsg returns EMSGSIZE when sending fd's via Unix domain datagram socket

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:10:23 25 4
gpt4 key购买 nike

我有一段代码使用 Unix 域套接字和 sendmsg/recvmsg 在两个进程之间发送 fd。此代码需要在 Linux 和 Mac 上运行(它针对两个平台分别编译)。我正在使用 SOCK_DGRAM(数据报)套接字。

我在代码中一次发送一个 fd。在 Mac 上,以这种方式成功发送几个 fd 后,recvmsg() 失败并显示 EMSGSIZE。根据 recvmsg 的联机帮助页,只有当 msg->msg_iovlen <=0 或 >= 在 Mac 上为 2048 的常量时才会发生这种情况。在我的代码中,我一直将 msg_iovlen 固定为 1,我在发送者和接收者上验证了这一点,并且在 recvmsg() 错误后立即读取消息头。同样的代码在 Linux 上运行良好。

通过查看 XNU 内核源代码,另一种可能性是接收器可能用完了 fd,但在错误发生之前我只发送了 4 或 5 个 fd,所以应该还有很多 fd。

如果我不发送 fd 而只发送数据,则不会发生此错误。

下面是打包控制消息的代码:

// *obj is the fd, objSize is sizeof(*obj)
// cmsg was allocated earlier as a 512 byte buffer

cmsgLength = CMSG_LEN(objSize);

cmsgSpace = CMSG_SPACE(objSize);

cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = cmsgLength;

memcpy(CMSG_DATA(cmsg), obj, objSize);

msg->msg_control = cmsg;
msg->msg_controllen = cmsgSpace;

这是接收器:

msg = (struct msghdr *)pipe->msg;
iov = msg->msg_iov;
iov->iov_base = buf;
iov->iov_len = size;

// msg->msg_control was set earlier
msg->msg_controllen = 512;

return recvmsg(sockFd, msg, 0);

有什么线索吗?提前致谢

最佳答案

你真的在使用你收到的 cmsg 东西吗?我注意到您将 msg_controllen 设置为 512。您将 msg_flags 设置为什么?

你能不能通过添加以下一项来尝试同样的事情。

msg = (struct msghdr *)pipe->msg;

memset (msg, 0, sizeof(msghdr)); /* added this */

iov = msg->msg_iov;
iov->iov_base = buf;
iov->iov_len = size;

// msg->msg_control was set earlier
msg->msg_controllen = 512;

return recvmsg(sockFd, msg, 0);

关于linux - 苹果操作系统 X : recvmsg returns EMSGSIZE when sending fd's via Unix domain datagram socket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17269252/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com