Michał Turek
Michał Turek

Reputation: 721

Creating server-socket connection without waiting for user input

My goal is to create a user-server connection. Most importantly I'm not willing to use threads. For now, I want it to work as a simple chat. I believe The issue is that It goes from one user to another in a loop waiting for their getline input, so technically only one user can send a message at a time. What I wish is that my code could handle multiple messages from one user continuously, not having to wait for all other users to send a message That's the running loop inside the server:

while (running)
{
    fd_set copy = master;

    // See who's talking to us
    int socketCount = select(0, &copy, nullptr, nullptr, nullptr);

    // Loop through all the current connections / potential connect
    for (int i = 0; i < socketCount; i++)
    {
        // Makes things easy for us doing this assignment
        SOCKET sock = copy.fd_array[i];

        // Is it an inbound communication?
        if (sock == listening)
        {
            // Accept a new connection
            sockaddr_in client;
            int clientSize = sizeof(client);
            SOCKET clientsocket = accept(listening, (sockaddr*)&client, &clientSize);

            // Add the new connection to the list of connected clients
            FD_SET(clientsocket, &master);

            // Send a welcome message to the connected client
            string welcomeMsg = "Welcome to the Awesome Chat Server!\r\n";
            send(clientsocket, welcomeMsg.c_str(), welcomeMsg.size() + 1, 0);
        }
        else // It's an inbound message
        {
            char buf[4096];
            ZeroMemory(buf, 4096);

            // Receive message
            int bytesIn = recv(sock, buf, 4096, 0);
            if (bytesIn <= 0)
            {
                // Drop the client
                closesocket(sock);
                FD_CLR(sock, &master);
            }
            else
            {
                
                // Send message to other clients, and definiately NOT the listening socket

                for (int i = 0; i < master.fd_count; i++)
                {
                    SOCKET outSock = master.fd_array[i];
                    if (outSock != listening && outSock != sock)
                    {
                        ostringstream ss;
                        ss << "SOCKET #" << sock << ": " << buf << "\r\n";
                        string strOut = ss.str();

                        send(outSock, strOut.c_str(), strOut.size() + 1, 0);
                    }
                }
            }
        }
    }
}

I belive this code should work, the issue is in my client code:

    char buf[4096];
     string userInput;

    do
    {
        // Prompt the user for some text
        cout << "> ";
        getline(cin, userInput); //THATS THE ISSUE, IT WAITS FOR GETLINE
        if (userInput.size() > 0)       // Make sure the user has typed in something
        {
            // Send the text
            int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
            if (sendResult != SOCKET_ERROR)
            {
                // Wait for response
                ZeroMemory(buf, 4096);
                int bytesReceived = recv(sock, buf, 4096, 0);
                if (bytesReceived > 0)
                {
                    // Echo response to console
                    cout << "SERVER> " << string(buf, 0, bytesReceived) << endl;
                }
            }
        }

    } while (userInput.size() > 0);

My question is if its really caused by getline and if so, how can it be fixed?

Upvotes: 0

Views: 378

Answers (1)

mzimmers
mzimmers

Reputation: 902

The answer to your question is "yes," but with a big proviso: a properly designed server shouldn't care what the client is doing. You might want to look into select() or, if you anticipate a large user community, poll(). You don't want a multi-user server to depend on/wait for a single client.

Upvotes: 1

Related Questions