简体   繁体   中英

Why does recvfrom() for a UNIX domain datagram socket return Invalid Argument?

I'm working on a program that uses UNIX domain datagram sockes for IPC. Half the time it works fine, but the other half it returns "Invalid argument". I've confirmed that this shouldn't be due to a socket path reuse error, SO_REUSEADDR is set on the socket and the error occurs even when any residual file in the socket path has been deleted. Why does this happen? Here's the code:

Server

/* receive data from the client and return a structure containing operation information and argument */
int handle_input(int server_socket, module *module_registry) {
        input client_input;     // operation and argument sent from client
        struct sockaddr *client_address;
        unsigned int cl_address_len;

        if(recvfrom(server_socket, &client_input, sizeof(input), 0, client_address, &cl_address_len) < 0) {
                fprintf(stderr, "failed to receive from datagram socket\n");
                perror("guru meditation");
                return 0;
        }

        /* parse input ... */
}

Client

int main(int argc, char **argv) {    
    /* parse input ... */

    /* initialize client socket and addressing information */
    if((client_socket = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
        fprintf(stderr, "failed to bind client socket\n");
        exit(1);
    }

    /* initialize server socket addressing information */
    memset(&server_addr, 0, sizeof(struct sockaddr_un));
    server_addr.sun_family = AF_UNIX;
    snprintf(server_addr.sun_path, sizeof server_addr.sun_path, "%s", SOCK_PATH);

    if(sendto(client_socket, &client_input, sizeof(input), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_un))
        fprintf(stderr, "failed to send message to daemon\n");
        exit(1);
    }

    exit(0);
}

Half the time it works fine, but the other half it returns "Invalid argument"

That is because cl_address_len needs to be initialized with the size of your address buffer but it contains an indeterminate value.

You need to make the following changes:

struct sockaddr_un client_address;
socklen_t cl_address_len = sizeof client_address;
if(recvfrom(server_socket, &client_input, sizeof(input), 0, (struct sockaddr*)&client_address, &cl_address_len) < 0) {

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM