c-即使文件描述为-1,SCM_RIGHTS协议类型中的套接字也可以发送数据



现在我使用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, '', 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, '', 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/Tim

否,您只能传递有效的文件描述符,并且-1永远不是有效的文件描述符(因为它在发生错误时返回(。

我建议在消息中包含一个特殊的字节(char(,描述错误——例如,作为消息中的第一个字符。如果传递了文件描述符,则为零;如果发生错误(描述错误的值(,则为非零。这样,有效负载数据的长度永远不会为零,这使得在发送任何数据之前更容易检测到套接字关闭。(零长度读取/接收通常表示输入结束,您可以看到。(

因为errno值不一定在机器之间匹配,所以应该将特殊字节值转换为errno代码,反之亦然。

或者,如果消息没有其他数据,可以将错误消息作为字符串发送,包括末尾的''字符串末尾标记;在传递文件描述符时仅使用CCD_ 3作为数据有效载荷。

最新更新