0

Here is my code:

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

void sServer::acceptClientConnections(int listenerSocket)
{
    struct sockaddr clientAddress;
    socklen_t sizeOfClientAddress = sizeof(clientAddress);

    while (true)
    {
        int newConnection  = accept(listenerSocket, &clientAddress, &sizeOfClientAddress);
        std::cout << "Someone connected ... " <<std::endl;
        liveConnections.push_back(newConnection);
    }
}

int sServer::getServerListenerSocket()
{
    return serverListenerSocket;
}

sServer::sServer(int port)
{
    int serverListenerSocket;
    struct sockaddr_in serv_addr;

    serverListenerSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverListenerSocket < 0) 
        error("ERROR opening a socket. Cannot start sever. Exiting ...");

    memset((char *) &serv_addr, 0, sizeof(serv_addr));

    serv_addr.sin_family =      AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port =        htons(port);

    std::cout << "Host ip: " << serv_addr.sin_addr.s_addr << "\n";

    if ( bind(serverListenerSocket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) 
        error("ERROR on binding server socket. Are you running another instance of this server ?");

    listen(serverListenerSocket, 45);
}

Called like this:

int main()
{
    sServer superServer(9889);
    std::thread handleConnections( &sServer::acceptClientConnections, superServer, superServer.getServerListenerSocket() );
}

I was expecting accept to wait for incoming connections, and when a connection comes in, become active.

But instead, when i run the program, it continuously prints "Someone connected ..." even though no connections are being made.

Ironically, if I start the thread at the end of the constructor, it works well.

Can you please explain why this is happening and what would be the correct way to accept a connection ?

Chani
  • 5,055
  • 15
  • 57
  • 92
  • Better check the return-value from the `accept` call. I'll bet it's `-1`. – Some programmer dude Aug 17 '14 at 12:32
  • @JoachimPileborg I put the check.. It does not print "Someone connected ... " even when I am connecting through telnet ands telnet says it successfully connected. Any ideas ? – Chani Aug 17 '14 at 12:39
  • And why does it work if the thread is created from inside the class (constructor) ? – Chani Aug 17 '14 at 12:40
  • Make up your mind. Either it prints this message continually as per your question or it doesn't print it at all as per your comment or else it prints it when there is a connection. Not all three at the same time. Are you storing the socket FD anywhere? It's a local variable in the constructor. – user207421 Aug 17 '14 at 16:48
  • @EJP after adding the -1 check it does not print it. The sock fd is a class member variable. – Chani Aug 17 '14 at 16:51
  • So you got an error. *What* error? And where are you storing into the class member? It doesn't happen in the code you posted. – user207421 Aug 17 '14 at 17:16
  • In my code, if you add a check for accept, you will find that you are able to connect to the server ( try with telnet) but the code will never print "Someone connected". That is what is weird. – Chani Aug 17 '14 at 17:19
  • Nothing weird about it. The socket is listening, so Telnet can connect, but accept() is failing, so you aren't processing the connection. I believe you are getting EBADF for the reason I gave above, but until you decide to tell us what error you got when accept() returned -1 it can't be certain. – user207421 Aug 17 '14 at 17:30
  • Thanks, I will check the exact error returned .. – Chani Aug 17 '14 at 17:31
  • I can't understand why you hadn't already done that. If a system call returns -1 it is an error. – user207421 Aug 17 '14 at 17:33
  • 1
    @I solved that problem by using the thread instantiation into the constructor (which some how works). I know I must go into the issue and actually find out what was wong but no time man. I am having another problem right now I cannot figure out. Can you please look into http://stackoverflow.com/questions/25351713/converting-parsing-google-protocol-buffer-streams-from-socket – Chani Aug 17 '14 at 17:37

1 Answers1

1

Now that we've determined the error, the problem is the local variable in the constructor:

sServer::sServer(int port)
{
    int serverListenerSocket;

Just remove it. It is shadowing the class member of the same name, so the latter is never getting set, so accept() is getting EBADF, returning -1, never displaying an accepted connection, smoking the CPU, etc.

The reason it works when you start the thread inside the constructor is that the local variable is still in scope.

user207421
  • 305,947
  • 44
  • 307
  • 483