Wie zu verwenden sendmsg() zum senden einer Datei-Deskriptor über sockets zwischen 2 Prozessen?

Nachdem @cnicutar antwortet mir auf diese Frage, ich habe versucht, so senden Sie eine Datei-Deskriptor von dem übergeordneten Prozess zu seinem Kind. Basierend auf dieser Beispiel, schrieb ich diesen code:

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);
    }

}

Aber leider bekam ich diese Fehlermeldung:

sendmsg(): Invalid argument

Was soll ich tun um dieses problem zu beheben? und bin ich mit der msghdr Struktur korrekt? weil in dem Beispiel, das ich oben erwähnt, Sie verwenden msg_accrights und msg_accrightslen und ich habe einige Fehler, wenn ich Sie nutzen, so hatte ich die Verwendung msg_name und msg_namelen statt.

InformationsquelleAutor Eng.Fouad | 2011-12-12

Schreibe einen Kommentar