Linux 套接字,accept() 函数,无效参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14317791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:39:29  来源:igfitidea点击:

Socket, accept() function, Invalid argument

clinuxsockets

提问by Dimofte Alex

I am getting an error "Invalid argument" when i call the accept() function on the server side of a client-server application. I don't get what is wrong and if you see what is wrong let me know please. Thanks.

当我在客户端-服务器应用程序的服务器端调用 accept() 函数时,出现错误“参数无效”。我不明白出了什么问题,如果您看到有什么问题,请告诉我。谢谢。

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>


int main(int argc, char* argv[])
{
    int sockfd, newsockfd, portno, len;
    struct sockaddr_in server, client;

    if(argc < 2){
        perror("Add more arguments");
    }

    sockfd = socket(AF_UNIX,SOCK_STREAM,0);
    if(sockfd < 0){
        perror("Error at socket()");    
    }
    printf("Socketfd: %d\n",sockfd);
    bzero((char *)&server, sizeof(server));
    portno = atoi(argv[1]);
    server.sin_family = AF_UNIX;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(portno);

    if(bind (sockfd, (struct sockaddr *)&server, sizeof(server)) <0){
        perror("Error at bind ()-server");  
    }

    listen(sockfd,5);

    int readval;
    char buffer[256];
    for(;;){
        len = sizeof(client);
        newsockfd = accept (sockfd, (struct sockaddr *)&server,&len);
        if (newsockfd == -1){
            perror("Erroare at accept()");      
        }
        else do{        
            readval = (sockfd,buffer,sizeof(buffer));
            if (readval < 0 ){
                perror("Error at reading()");       
            }
            else if (readval == 0){
                printf("End conection");            
            }
            else{
                printf("Mesage is: %s\n", buffer);
            }
        }while (readval > 0);
        close(newsockfd);
    }
    return 0;   
}

采纳答案by Davide Berra

You have to use sockaddr_uninstead of sockaddr_infor Unix domain sockets OR substitute AF_UNIXwith AF_INET.

您必须使用sockaddr_un而不是sockaddr_inUnix 域套接字或替换AF_UNIXAF_INET.

Plus, check the return of listen.

另外,检查听的返回。

Plus change this line

加上改变这一行

readval = (sockfd,buffer,sizeof(buffer));

with

readval = read(newsockfd,buffer,sizeof(buffer));

because data is going to be sent through the newly created socket and not on the listening one

因为数据将通过新创建的套接字发送,而不是在侦听套接字上发送

Plus, as mentioned by @trojanfoe, subst the serverwith the clientstructure into the accept()call

另外,正如@trojanfoe 所提到的server,将client结构替换为accept()调用

回答by trojanfoe

This line:

这一行:

newsockfd = accept (sockfd, (struct sockaddr *)&server, &len);

Should be:

应该:

newsockfd = accept (sockfd, (struct sockaddr *)&client, &len);

From the manpage:

联机帮助页

The argument addr is a pointer to a sockaddr structure. This structure is filled in with the address of the peer socket, as known to the communications layer. The exact format of the address returned addr is determined by the socket's address family (see socket(2) and the respective protocol man pages). When addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL.

参数 addr 是指向 sockaddr 结构的指针。这个结构用通信层已知的对等套接字的地址填充。返回 addr 的地址的确切格式由套接字的地址族确定(请参阅 socket(2) 和相应的协议手册页)。当addr为NULL时,什么都不填;在这种情况下,不使用 addrlen,也应该是 NULL。

Also check the return value from listen().

还要检查从listen().

回答by jarr

I ran into a similar issue before and it was due to not having the read function in a loop. Here is an example I did before.

我之前遇到过类似的问题,这是由于没有循环读取函数。这是我之前做的一个例子。

while (1) {
        new_sockfd = accept(sockfd, (struct sockaddr *) &client_addr,
                 &sin_size);
        if (new_sockfd == -1)
            perror("accepting connection");
        printf("server: got connection from %s port %d\n",
            inet_ntoa(client_addr.sin_addr),
            ntohs(client_addr.sin_port));
        recv_length = recv(new_sockfd, &buffer, DATA, 0);

        while (recv_length > 0) {
            printf("RECV: %d bytes\n", recv_length);
            dump(buffer, recv_length);
            recv_length = recv(new_sockfd, &buffer, DATA, 0);
        }

        close(new_sockfd);
    }