Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9201235
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 17, 20262026-06-17T22:57:24+00:00 2026-06-17T22:57:24+00:00

I have a working server that can handle multiple clients (one thread per client)

  • 0

I have a working server that can handle multiple clients (one thread per client) – adapted from here. At the moment it works like this:

  1. Client connects to server
  2. User types message on client console which is sent to server (and displayed on server-side console.
  3. User types message on server console which is sent back to the same client.

But what I would like to do is receive a message from e.g. client 1, which goes to the server for processing, and then may be forwarded to client 3 (which client it forwards the message to is determined by server).

My guess is that I need to modify the clientHandleThread, but I don’t know what I need to do. I’m also not sure if it is possible to access a separate thread from the current one.

I am very new to socket programming and threads, and trying hard to learn and so would welcome any help! I am attaching the code containing main() (please let me know if I should attach other code!)

myLog winLog;

DWORD WINAPI clientHandleThread(LPVOID threadInfo)
{
    //this structure will contain all the data this callback will work on
    myThreadArgument* clientArgument = (myThreadArgument*)threadInfo;

    //the semamphore to protect the access to the std output
    mySemaphore* coutSemaphore = clientArgument->getCoutSemaphore();

    /*get the client connection: receiving messages from client and
    sending messages to the client will all be done by using
    this client connection*/
    myTcpSocket* clientConnection = clientArgument->getClientConnect();
    string clientName = clientArgument->getHostName();

    //the server is communicating with this client here
    while(1)
    {
        string messageFromClient = "";

        //receive from the client

        int numBytes = clientConnection->receiveMessage(messageFromClient);
        if ( numBytes == -99 ) break;

        //write to the console and the log file, so lock the semaphore
        coutSemaphore->lock();

        cout   << "[RECV fr " << clientName << "]: " << messageFromClient << endl;
        winLog << "[RECV fr " << clientName << "]: " << messageFromClient << endl;

        msgInfo proMsgFrCli = msgClassification(messageFromClient);

        //if the client wants to discount
        if ( messageFromClient.compare("quit") == 0 || messageFromClient.compare("Quit") == 0 )
        {
            coutSemaphore->unlock();
            break;
        }
        else // send to the client
        {
            char messageToClient[MAX_MSG_LEN+1];
            memset(messageToClient,0,sizeof(messageToClient));
            cout << "[SEND to " << clientName << "]: ";
            cin.getline(messageToClient,MAX_MSG_LEN);
            winLog << "[SEND to " << clientName << "]: " << messageToClient << endl;
            clientConnection->sendMessage(string(messageToClient));
            coutSemaphore->unlock();
        }
    }

    // if we reach here, this session with the client is done,
    // so we set the event on this thread to inform the main
    // control that this session is finished
    clientArgument->getExitEvent()->setEvent();
    return 1;
}

DWORD WINAPI serverHandleThread(LPVOID threadInfo) //server thread
{
    //this structure will contain all the data this callback will work on
    myThreadArgument* serverArgument = (myThreadArgument*)threadInfo;

    //the semamphore to protect the access to the std output
    mySemaphore* coutSemaphore = serverArgument->getCoutSemaphore();

    //get the server
    myTcpSocket* myServer = serverArgument->getClientConnect();
    string serverName = serverArgument->getHostName();

    //bind the server to the socket
    myServer->bindSocket();
    cout   << endl << "server finishes binding process... " << endl;
    winLog << endl << "server finishes binding process... " << endl;

    //server starts to wait for client calls
    myServer->listenToClient();
    cout   << "server is waiting for client calls ... " << endl;
    winLog << "server is waiting for client calls ... " << endl;

    //server starts to listen, and generates a thread to handle each client
    myThreadArgument* clientArgument[MAX_NUM_CLIENTS];
    myThread* clientHandle[MAX_NUM_CLIENTS];
    for ( int i = 0; i < MAX_NUM_CLIENTS; i++ )
    {
        clientArgument[i] = NULL;
        clientHandle[i] = NULL;
    }
    int currNumOfClients = 0;
    char buffer [100]; //temp buffer to convert currNumOfClients to char

    while ( 1 )
    {
        //wait to accept a client connection.  
        //processing is suspended until the client connects
        myTcpSocket* client; //connection dedicated for client communication
        string clientName; //client name 
        client = myServer->acceptClient(clientName);    
        clientName = clientName + "-" + itoa(currNumOfClients, buffer, 10);//char(65+currNumOfClients);

        //lock the std out so we can write to the console
        coutSemaphore->lock();
        cout   << endl << endl << "==> a client from [" << clientName << "] is connected!" << endl;
        winLog << endl << "==> a client from [" << clientName << "] is connected!" << endl << endl;

        coutSemaphore->unlock();

        //for this client, generate a thread to handle it
        if ( currNumOfClients < MAX_NUM_CLIENTS-1 )
        {
            clientArgument[currNumOfClients] = new myThreadArgument(client,coutSemaphore,clientName);
            clientHandle[currNumOfClients] = new myThread(clientHandleThread,(void*)clientArgument[currNumOfClients]);
            serverArgument->addClientArgument(clientArgument[currNumOfClients]);
            clientHandle[currNumOfClients]->execute();
            currNumOfClients++;
        }
    }

    return 1;
}

int main()
{
    /*build a semaphore so we can synchronize the access to std cout
    also includes the log file*/
    mySemaphore coutSemaphore(string(""),1);

    //initialize the winsock library
    myTcpSocket::initialize();

    /*create the server: local host will be used as the server, let us 
    first use myHostInfo class to show the name and IP address 
    of the local host*/
    winLog << endl;
    winLog << "retrieve the local host name and address:" << endl;

    myHostInfo serverInfo;
    string serverName = serverInfo.getHostName();
    string serverIPAddress = serverInfo.getHostIPAddress();
    cout << "my localhost (server) information:" << endl;
    cout << "   name:    " << serverName << endl;
    cout << "   address: " << serverIPAddress << endl;
    winLog << "     ==> name: " << serverName << endl;
    winLog << "     ==> address: " << serverIPAddress << endl;

    //open socket on the local host(server) and show its configuration
    myTcpSocket myServer(PORTNUM);
    cout   << myServer;
    winLog << myServer;

    //read connectivityFile
    neighbourInfo = connFrFile(numberOfFiles, intBtwnChange);
    //read routingFile
    nextHopInfo = routFrFile(numberOfFiles, intBtwnChange);

    /*create a thread to implement server process: listening to the socket,
    accepting client calls and communicating with clients. This will free the 
    main control (see below) to do other process*/
    myThreadArgument* serverArgument = new myThreadArgument(&myServer,&coutSemaphore,serverName);
    myThread* serverThread = new myThread(serverHandleThread,(void*)serverArgument);
    serverThread->execute();

    // main control: since the serverThread is handling the server functions,
    // this main control is free to do other things.
    while ( 1 )
    {
        /*do whatever you need to do here, I am using Sleep(x) 
        to make a little delay, pretending to be the other 
        possible processings*/
        Sleep(50000);

        //report the server status
        coutSemaphore.lock();
        cout   << endl << "-----------------------------------------------------------------" << endl;
        winLog << endl << "-----------------------------------------------------------------" << endl;
        cout   << "server (name:" << serverName << ") status report:" << endl;
        winLog << "server (name:" << serverName << ") status report:" << endl;
        cout   << "   the following clients have successfully connected with server: " << endl;
        winLog << "   the following clients have successfully connected with server: " << endl;
        for ( int i = 0; i < MAX_NUM_CLIENTS; i ++ )
        {
            myThreadArgument* clientInfo = serverArgument->getClientArgument(i);
            if ( clientInfo ) 
            {
                cout   << "         " << clientInfo->getHostName() << endl;
                winLog << "         " << clientInfo->getHostName() << endl;
            }
        }
        cout   << "   the following clients have shutdown the connection: " << endl;
        winLog << "   the following clients have shutdown the connection: " << endl;
        for ( int i = 0; i < MAX_NUM_CLIENTS; i ++ )
        {
            myThreadArgument* clientInfo = serverArgument->getClientArgument(i);
            if ( clientInfo && clientInfo->getExitEvent()->waitForEvent(0) )
            {
                clientInfo->setSignalToEnd(true);
                cout   << "         " << clientInfo->getHostName() << endl;
                winLog << "         " << clientInfo->getHostName() << endl;
            }
        }
        cout   << "-----------------------------------------------------------------" << endl << endl;
        winLog << "-----------------------------------------------------------------" << endl << endl;
        coutSemaphore.unlock();
    }

    return 1;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-17T22:57:26+00:00Added an answer on June 17, 2026 at 10:57 pm

    For each connection you can have two queues: One for input, and one for output. The connections thread (if you have one dedicated thread per connection) reads input from the client and puts it in the input queue. The connection-thread also fetches messages from the output queue and sends it to the connected client.

    The server then has another thread, that goes through all connections input queues, extracts the messages, decides what to do with the input, and then possibly puts it into the output queue of some other connection.


    Pseudo-code example:

    struct message_struct
    {
        int source;       // Source where the message came from
        int destination;  // Destination client to send message on to
    }
    
    void client_thread()
    {
        while (!exit_thread)
        {
            if (is_there_anything_to_recv())
            {
                // Receive and parse a message from the client
                message = receive();
    
                // Add to the threads input queue
                add_to_queue(input_queue, message);
            }
    
            // As long as there are messages in the output queue
            while (!queue_is_empty(output_queue))
            {
                // Remove one message from the queue
                message = remove_from_queue(output_queue);
    
                // And send it to the connected client
                send(message);
            }
        }
    }
    
    void server_thread()
    {
        while (!exit_thread)
        {
            // Check for new connections
            // ...
    
            // Assuming the threads are on array (or array-like structure)
            for (i = 0; i < number_of_client_threads; i++)
            {
                // While the current threads (`i`)  input queue is not empty
                while (!queue_is_empty(client_threads[i].input_queue))
                {
                    // Remove the message from the threads input queue
                    message = remove_from_queue(client_threads[i].input_queue);
    
                    // And add it to the destinations output queue
                    add_to_queue(client_threads[message.destination].output_queue);
                }
            }
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have been working on designing a file server that could take the load
I'm working within a platform that I do not have server side access to
I have been working with SQL Server as a Developer a while. One thing
I am working on a server-side framework. Here and there I have been adding
I'm working on a small distributed computing project. The server can't handle the calculations
Here is my issue. I'm working on an App for a client so that
I'm working on a little client that interfaces with a game server. The server
I have a working gitolite server. However, I want to move it to an
There are databases on Firebird and SQL Server. I have working stored procedure in
I have a basic server working but I want to be able to press

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.