在@cnicutar在这个question上回答我之后,我试图从父进程向其子进程发送一个文件描述符.基于这个example,我写了这段代码:
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,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,sizeof(child_msg));
memset(iov,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,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_accrights和msg_accrightslen,当我使用它时出现了一些错误,所以我不得不使用msg_name和msg_namelen.
最佳答案
原文链接:https://www.f2er.com/linux/440570.html