通过 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]。

我做错了什么?

来自Cloudflare blog

从技术上讲,您不会发送“文件描述符”。您在代码中处理的“文件描述符”只是进程本地文件描述符 table 的索引,它又指向 OS 打开的文件 table,最终指向代表文件的 vnode。因此,尽管指向同一个文件,其他进程观察到的“文件描述符”很可能具有不同的数值。