如何使用sendmsg()通过2个进程之间的套接字发送文件描述符?

@cnicutar在此问题上回答了我之后,我尝试将文件描述符从父进程发送到其子进程。基于此示例,我编写了以下代码:

int socket_fd ,accepted_socket_fd, on = 1;

int server_sd, worker_sd, pair_sd[2];

struct sockaddr_in client_address;

struct sockaddr_in server_address;

/* =======================================================================

* Setup the network socket.

* =======================================================================

*/

if((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

{

perror("socket()");

exit(EXIT_FAILURE);

}

if((setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on))) < 0)

{

perror("setsockopt()");

exit(EXIT_FAILURE);

}

server_address.sin_family = AF_INET; /* Internet address type */

server_address.sin_addr.s_addr = htonl(INADDR_ANY); /* Set for any local IP */

server_address.sin_port = htons(port); /* Set to the specified port */

if(bind(socket_fd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)

{

perror("bind()");

exit(EXIT_FAILURE);

}

if(listen(socket_fd, buffers) < 0)

{

perror("listen()");

exit(EXIT_FAILURE);

}

if(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair_sd) < 0)

{

socketpair("bind()");

exit(EXIT_FAILURE);

}

server_sd = pair_sd[0];

worker_sd = pair_sd[1];

/* =======================================================================

* Worker processes

* =======================================================================

*/

struct iovec iov[1];

struct msghdr child_msg;

char msg_buffer[80];

int pass_sd, rc;

/* Here the parent process create a pool of worker processes (its children) */

for(i = 0; i < processes; i++)

{

if(fork() == 0)

{

// ...

/* Loop forever, serving the incoming request */

for(;;)

{

memset(&child_msg, 0, sizeof(child_msg));

memset(iov, 0, sizeof(iov));

iov[0].iov_base = msg_buffer;

iov[0].iov_len = sizeof(msg_buffer);

child_msg.msg_iov = iov;

child_msg.msg_iovlen = 1;

child_msg.msg_name = (char *) &pass_sd;

child_msg.msg_namelen = sizeof(pass_sd);

printf("Waiting on recvmsg\n");

rc = recvmsg(worker_sd, &child_msg, 0);

if (rc < 0)

{

perror("recvmsg() failed");

close(worker_sd);

exit(-1);

}

else if (child_msg.msg_namelen <= 0)

{

printf("Descriptor was not received\n");

close(worker_sd);

exit(-1);

}

else

{

printf("Received descriptor = %d\n", pass_sd);

}

//.. Here the child process can handle the passed file descriptor

}

}

}

/* =======================================================================

* The parent process

* =======================================================================

*/

struct msghdr parent_msg;

size_t length;

/* Here the parent will accept the incoming requests and passed it to its children*/

for(;;)

{

length = sizeof(client_address);

if((accepted_socket_fd = accept(socket_fd, NULL, NULL)) < 0)

{

perror("accept()");

exit(EXIT_FAILURE);

}

memset(&parent_msg, 0, sizeof(parent_msg));

parent_msg.msg_name = (char *) &accepted_socket_fd;

parent_msg.msg_namelen = sizeof(accepted_socket_fd);

if((sendmsg(server_sd, &parent_msg, 0)) < 0)

{

perror("sendmsg()");

exit(EXIT_FAILURE);

}

}

但是不幸的是,我得到了这个错误:

sendmsg(): Invalid argument

我应该怎么做才能解决这个问题?我msghdr是否正确使用该结构?因为在我上面提到的示例中,它们使用msg_accrightsmsg_accrightslen,当我使用它们时遇到了一些错误,因此我不得不使用msg_namemsg_namelen

回答:

这是很难做到的。我建议仅使用为您提供帮助的图书馆。最简单的一种是libancillary。它提供了两种功能,一种是通过UNIX域套接字发送文件描述符,另一种是接收文件描述符。它们使用起来非常荒谬。

以上是 如何使用sendmsg()通过2个进程之间的套接字发送文件描述符? 的全部内容, 来源链接: utcz.com/qa/423115.html

回到顶部