简体   繁体   English

为什么 UNIX 域数据报套接字的 recvfrom() 返回无效参数?

[英]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.我正在开发一个将 UNIX 域数据报袜子用于 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.我已经确认这不应该是由于套接字路径重用错误,套接字上设置了 SO_REUSEADDR,即使删除了套接字路径中的任何残留文件,也会发生错误。 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.那是因为cl_address_len需要使用地址缓冲区的大小进行初始化,但它包含一个不确定的值。

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) {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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