linux fork socketpair sock_dgram

2019-08-18 06:14发布

问题:

I'm new to socketpairs and I need my children each to pass information from a structure to the parent.I was told this can be done using SOCK_DGRAM but I don't know how to do it.I looked over the internet but i couldn't find a concrete example.Can you please show for example hoe can you pass to the parent a structure made out of 2 ints and a string maybe ?I just want an example so I can understand how I could build this kind of socketpair and send information through it.Thank you

回答1:

How about the following:

int sockets[2];
if (socketpair(AF_INET, SOCK_DGRAM, 0, sockets) != -1)
{
    int res = fork();

    if (res == 0)
    {
        /* In child process */

        /* We only need one socket, so close the other */
        close(sockets[0]);

        struct some_structure my_struct;

        write(sockets[1], &my_struct, sizeof(my_struct));

        /* All done */
        exit(0);
    }
    else if (res > 0)
    {
        /* In parent process */

        /* We only need one socket, so close the other */
        close(sockets[1]);

        struct some_structure my_struct;

        read(sockets[0], &my_struct, sizeof(my_struct));
    }
}

The above code doesn't check for, or handle, errors. It can't handle structures containing pointers, structures using arrays are okay though.



回答2:

Assuming that your string is represented as a char* as in

struct data {
    int i, j;
    char *s;
};

you need to devise some serialization format, because sending a pointer won't work; the pointee is not passed so it won't point to anything useful in the receiver (the parent). A simple format would be to put the integers end-to-end, then directly append the string including its NUL terminator, so you'd get

int senddata(int fd, struct data const *d)
{
    size_t msglen = 2 * sizeof(int) + strlen(d->s) + 1;
    char *msg = malloc(msglen);

    if (msg == NULL)
        return -1;

    ((int *)msg)[0] = d->i;
    ((int *)msg)[1] = d->j;
    strcpy(msg + 2 * sizeof(int), d->s);

    ssize_t r = send(fd, msg, msglen, 0);

    free(msg);
    return r;
}

with a corresponding receive function for the parent. You might want to put some maximum length on the string, because the parent needs to know the size of the message in advance.