George Sp
George Sp

Reputation: 572

Socket accept invalid argument (c++)

I am trying to create a web-server which will accept requests and commands from sockets (in different ports). I have some demo code for simple socket communication, which compiles and runs as expected, but when I run mine (written with demo as a reference, that is why there are some printf's) accept() fails with :

"invalid argument" as error. I can not find what is wrong.

Any suggestion/correction is appreciated.

Here is my code:

#include <iostream>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <cstring>
#include <cstdlib>
#include <cstddef>

void perror_exit(char *message);
void thread_run();

int main(int argc, char const *argv[])
{

    int i, filepos, serving_port=0, command_port=0, thread_num=0;
    char *root_dir = (char *)malloc(sizeof(char *));

    int serv_sock=0, command_sock=0, new_sock_c, new_sock_s=0;

    struct sockaddr_in server,commands;
    struct sockaddr_in server_client,commands_client;

    struct sockaddr *serverptr=(struct sockaddr *)&server;
    struct sockaddr *commandsptr=(struct sockaddr *)&commands;

    struct sockaddr *server_clientptr=(struct sockaddr *)&server_client;
    struct sockaddr *commands_clientptr=(struct sockaddr *)&commands_client;

    socklen_t clientlen_s, clientlen_c;
    struct hostent *rem_s, *rem_c;

    socklen_t clientlen;
    if(argc != 9){
        perror("Wrong number of arguments, webServer");
        exit(1);
    }else{

        for (i=0;i<argc;i++){
            if (strcmp(argv[i],"-p") == 0){
                serving_port = atoi(argv[i+1]);
            }
        }

        for (i=0;i<argc;i++){
            if (strcmp(argv[i],"-c") == 0){
                command_port = atoi(argv[i+1]);
            }
        }

        for (i=0;i<argc;i++){
            if (strcmp(argv[i],"-t") == 0){
                thread_num = atoi(argv[i+1]);
            }
        }

        for (i=0;i<argc;i++){
            if (strcmp(argv[i],"-d") == 0){
                filepos = i+1;
                strncpy(root_dir, argv[i+1], strlen(argv[i+1])+1); //   +1 to get "\n" too, without +1 seg fault appears
            }
        }

    }

    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(serving_port);

    commands.sin_family = AF_INET;
    commands.sin_addr.s_addr = htonl(INADDR_ANY);
    commands.sin_port = htons(command_port);

    if ((serv_sock = socket(AF_INET,SOCK_STREAM,0)) == -1)
    {
        perror_exit("Failed to create serving socket");
        // return -1;
    }

    if ((command_sock = socket(AF_INET,SOCK_STREAM,0)) == -1)
    {
        perror_exit("Failed to create command socket");
        // return -1;
    }

    if (bind(serv_sock, serverptr, sizeof(server)) < 0)
        perror_exit("bind");
    printf("Listening for connections to port %d\n", serving_port);

    if (bind(command_sock, commandsptr, sizeof(server)) < 0)
        perror_exit("bind");
    printf("Listening for commands to port %d\n", command_port);

    while(true)
    {
        clientlen_s = sizeof(server_client);
        clientlen_c = sizeof(commands_client);

        if ((new_sock_s = accept(serv_sock, server_clientptr, &clientlen_s)) < 0)
            perror_exit("accept (server)");

        if ((new_sock_c = accept(command_sock, commands_clientptr, &clientlen_c)) < 0)
            perror_exit("accept (commands)");

        if ((rem_s = gethostbyaddr((char *) &server_client.sin_addr.s_addr, sizeof(server_client.sin_addr.s_addr), server_client.sin_family)) == NULL) {
            herror("gethostbyaddr"); exit(1);
        }
        printf("Accepted serving connection from %s\n", rem_s->h_name);

        if ((rem_c = gethostbyaddr((char *) &commands_client.sin_addr.s_addr, sizeof(commands_client.sin_addr.s_addr), commands_client.sin_family)) == NULL) {
            herror("gethostbyaddr"); exit(1);
        }
        printf("Accepted command connection from %s\n", rem_c->h_name);


    }
    /* code */
    return 0;
}

void perror_exit(char *message)
{
    perror(message);
    exit(EXIT_FAILURE);
}


void thread_run()
{

}

Upvotes: 1

Views: 1063

Answers (1)

mpromonet
mpromonet

Reputation: 11942

Before calling accept, you should call listen.

From accept manual :

   EINVAL Socket is not listening for connections, or addrlen is invalid
          (e.g., is negative).

You should add before the loop:

 listen(serv_sock,5);
 listen(command_sock,5);

However in order to not block in the accept call if no connection is pending, you should consider to use select or poll.
This will allow to check if connection is pending before calling accept

Upvotes: 4

Related Questions