我有一段代码使用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);
任何线索? 提前致谢
答案 0 :(得分: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);