【发布时间】:2021-07-21 22:21:27
【问题描述】:
现在我使用 SCM_RIGHTS 协议来发送 fd(文件描述)。但有时我的 fd 由于某种原因会得到 -1。而且我想告诉接收者,即使在这个时候,发送者也有错。
但是当我使用“sendmsg”时会得到:发送消息失败:文件描述符错误
我的发件人代码如下:
int32_t SendFrame(const char *sockPath, char *sendFrameInfo, uint32_t sendFrameInfoLen,
int32_t inFd) {
int SockFd = socket(AF_UNIX, SOCK_DGRAM, 0);
struct sockaddr_un peer;
/* Create name. */
peer.sun_family = AF_UNIX;
strcpy(peer.sun_path, sockPath);
int ret = connect(SockFd, (struct sockaddr *)&peer, sizeof(struct sockaddr_un));
struct msghdr msg = {0};
struct cmsghdr *cmsg;
char buf[CMSG_SPACE(sizeof(int))];
memset(buf, '\0', sizeof(buf));
struct iovec io = {.iov_base = (void *)sendFrameInfo, .iov_len = sendFrameInfoLen};
msg.msg_iov = &io;
msg.msg_iovlen = 1;
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
memcpy((int *)CMSG_DATA(cmsg), &inFd, sizeof(int));
if (sendmsg(SockFd, &msg, 0) < 0) {
printf("SendFrame(%s) Failed to send message: %s", sockPath, strerror(errno));
return -1;
}
return 0;
};
下面是我的接收器代码:
int32_t recvFrame(char *buf, int32_t fd, uint32_t timeout_ms, uint32_t bufsize) {
struct msghdr msg = {0};
struct cmsghdr *cmsg;
char msg_control[CMSG_SPACE(sizeof(int))];
memset(msg_control, '\0', sizeof(msg_control));
struct iovec io = { .iov_base = &buf, .iov_len = bufsize };
msg.msg_iov = &io;
msg.msg_iovlen = 1;
msg.msg_control = msg_control;
msg.msg_controllen = sizeof(msg_control);
struct timeval timeout;
timeout.tv_sec = timeout_ms / 1000;
timeout.tv_usec = (timeout_ms % 1000) * 1000;
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
ssize_t len = recvmsg(fd, &msg, 0);
if (len < 0) {
perror("Failed to receive message");
return -errno;
}
cmsg = CMSG_FIRSTHDR(&msg);
int new fd = *((int32_t *)CMSG_DATA(cmsg));
return 0;
}
现在我可以使用那么我如何使用“msg_iov”来发送其他消息。所以我想接收消息事件发送者的 fd 是 -1 然后我可以检查“msg_iov”发生了什么。
谢谢!
BR/蒂姆
【问题讨论】: