Search code examples
c++multithreadingsocketsobjectrecv

Multithreading in C++, receive message from socket


I have studied Java for 8 months but decided to learn some c++ to on my spare time.

I'm currently making a multithreaded server in QT with minGW. My problem is that when a client connects, I create an instance of Client( which is a class) and pass the socket in the client class contructor.

And then I start a thread in the client object (startClient()) which is going to wait for messages, but it doesn't. Btw, startClient is a method that I create a thread from. See code below.

What happens then? Yes, when I try to send messages to the server, only errors, the server won't print out that a new client connects, and for some reason my computer starts working really hard. And qtcreator gets super slow until I close the server-program.

What I actually is trying to achieve is an object which derives the thread, but I have heard that it isn't a very good idea to do so in C++.

The listener loop in the server:

for (;;)
    {
        if ((sock_CONNECTION = accept(sock_LISTEN, (SOCKADDR*)&ADDRESS, &AddressSize)))
        {
            cout << "\nClient connected" << endl;

            Client client(sock_CONNECTION); // new object and pass the socket
            std::thread t1(&Client::startClient, client); //create thread of the method
            t1.detach();
        }
    }

the Client class:

Client::Client(SOCKET socket)
{
    this->socket = socket;
    cout << "hello from clientconstructor ! " << endl;
}

void Client::startClient()
{
    cout << "hello from clientmethod ! " << endl;

    // WHEN I ADD THE CODE BELOW I DON'T GET ANY OUTPUT ON THE CONSOLE!
    // No messages gets received either.
    char RecvdData[100] = "";
    int ret;
    for(;;)
    {

        try
        {
            ret = recv(socket,RecvdData,sizeof(RecvdData),0);
            cout << RecvdData << endl;
        }
        catch (int e)
        {
            cout << "Error sending message to client" << endl;
        }

    }
}

Solution

  • The fact that you never see any output from the Server likely means that your client is unable to connect to your Server in the first place. Check that you are doing your IP addressing correctly in your connect calls. If that looks good, then maybe there is a firewall blocking the connection. Turn that off or open the necessary ports.

    Your connecting client is likely getting an error from connect that it is interpreting as success and then trying to send lots of traffic on an invalid socket as fast as it can, which is why your machine seems to be working hard.

    You definitely need to check the return values from accept, connect, read and write more carefully. Also, make sure that you aren't running your Server's accept socket in non-blocking mode. I don't think that you are because you aren't seeing any output, but if you did it would infinitely loop on error spawning tons of threads that would also infinitely loop on errors and likely bring your machine to its knees.

    If I misunderstood what is happening and you do actually get a client connection and have "Client connected" and "hello from client method ! " output, then it is highly likely that your calls to recv() are failing and you are ignoring the failure. So, you are in a tight infinite loop that is repeatedly outputting "" as fast as possible.

    You also probably want to change your catch block to catch (...) rather than int. I doubt either recv() or cout throw an int. Even so, that catch block won't be invoked when recv fails because recv doesn't throw any exceptions AFAIK. It returns its failure indicator through its return value.