通过 Linux 套接字发送和接收整数数组
Sending and receiving integers array by Linux socket
我正在尝试使用 C++ 通过 linux 套接字传递一个整数数组(文件描述符)。
我用cmgs(3) and seccomp_unotify(2)写了下面的发送和接收函数:
发送:
static bool send_fds(int socket) // send array of fds by socket
{
int myfds[] = {568, 519, 562, 572, 569 ,566}; //static values for testing
struct msghdr msg = { 0 };
struct cmsghdr *cmsg;
char iobuf[1];
struct iovec io = {
.iov_base = iobuf,
.iov_len = sizeof(iobuf)
};
union {
char buf[CMSG_SPACE(sizeof(myfds))];
struct cmsghdr align;
} u;
msg.msg_iov = &io;
msg.msg_iovlen = 1;
msg.msg_control = u.buf;
msg.msg_controllen = sizeof(u.buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(myfds));
memcpy(CMSG_DATA(cmsg), &myfds, sizeof(myfds));
if (sendmsg (socket, &msg, 0) < 0)
{
return false;
}
return true;
}
收到:
static int * read_fds(int sockfd)
{
struct msghdr msgh;
struct iovec iov;
int data[6], fd[6];
ssize_t nr;
union {
char buf[CMSG_SPACE(sizeof(fd))];
struct cmsghdr align;
} controlMsg;
struct cmsghdr *cmsgp;
msgh.msg_name = NULL;
msgh.msg_namelen = 0;
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
iov.iov_base = &data;
iov.iov_len = sizeof(fd);
msgh.msg_control = controlMsg.buf;
msgh.msg_controllen = sizeof(controlMsg.buf);
recvmsg(sockfd, &msgh, 0);
cmsgp = CMSG_FIRSTHDR(&msgh);
memcpy(&fd, CMSG_DATA(cmsgp), sizeof(int)*6);
return fd;
}
无论我发送什么,接收函数中的数组都是[8,9,10,11,12,13]。
我做错了什么?
从技术上讲,您不会发送“文件描述符”。您在代码中处理的“文件描述符”只是进程本地文件描述符 table 的索引,它又指向 OS 打开的文件 table,最终指向代表文件的 vnode。因此,尽管指向同一个文件,其他进程观察到的“文件描述符”很可能具有不同的数值。
我正在尝试使用 C++ 通过 linux 套接字传递一个整数数组(文件描述符)。
我用cmgs(3) and seccomp_unotify(2)写了下面的发送和接收函数:
发送:
static bool send_fds(int socket) // send array of fds by socket
{
int myfds[] = {568, 519, 562, 572, 569 ,566}; //static values for testing
struct msghdr msg = { 0 };
struct cmsghdr *cmsg;
char iobuf[1];
struct iovec io = {
.iov_base = iobuf,
.iov_len = sizeof(iobuf)
};
union {
char buf[CMSG_SPACE(sizeof(myfds))];
struct cmsghdr align;
} u;
msg.msg_iov = &io;
msg.msg_iovlen = 1;
msg.msg_control = u.buf;
msg.msg_controllen = sizeof(u.buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(myfds));
memcpy(CMSG_DATA(cmsg), &myfds, sizeof(myfds));
if (sendmsg (socket, &msg, 0) < 0)
{
return false;
}
return true;
}
收到:
static int * read_fds(int sockfd)
{
struct msghdr msgh;
struct iovec iov;
int data[6], fd[6];
ssize_t nr;
union {
char buf[CMSG_SPACE(sizeof(fd))];
struct cmsghdr align;
} controlMsg;
struct cmsghdr *cmsgp;
msgh.msg_name = NULL;
msgh.msg_namelen = 0;
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
iov.iov_base = &data;
iov.iov_len = sizeof(fd);
msgh.msg_control = controlMsg.buf;
msgh.msg_controllen = sizeof(controlMsg.buf);
recvmsg(sockfd, &msgh, 0);
cmsgp = CMSG_FIRSTHDR(&msgh);
memcpy(&fd, CMSG_DATA(cmsgp), sizeof(int)*6);
return fd;
}
无论我发送什么,接收函数中的数组都是[8,9,10,11,12,13]。
我做错了什么?
从技术上讲,您不会发送“文件描述符”。您在代码中处理的“文件描述符”只是进程本地文件描述符 table 的索引,它又指向 OS 打开的文件 table,最终指向代表文件的 vnode。因此,尽管指向同一个文件,其他进程观察到的“文件描述符”很可能具有不同的数值。