views:

46

answers:

1

Hey,

I am writing on a small tcp chat server, but I am encountering some problems I can´t figure out how to solve "elegantly".

Below is the code for my main loop: it does:
1.Initiates a vector with the basic event, which is flagged, when a new tcp connection is made.
2. gets this connection and pushes it back into a vector, too. Then with the socket it creates a CSingleConnection object and passes the socket into it.
2.1. gets the event from the CSingleConnection, which is flagged when the connection receives data...
3. when it receives data. the wait is fullfilled and returns the number of the handle in the array... with all those other vectors it seems i can determine which one is sending now...

but as everybody can see: this methodology is really poorly... I cant figure out how to do all this better, with getting the connection socket, creating a single connection and so on :/...

Any suggestions, improvements, etc?...

void CServer::MainLoop()
{
    DWORD dwResult = 0;
    bool bMainLoop = true;
    std::vector<std::string> vecData;
    std::vector<HANDLE> vecEvents;              //Contains the handles to wait on
    std::vector<SOCKET> vecSocks;               //contains the sockets
    enum
    {
        ACCEPTOR = 0,           //First element: sequence is mandatory

        EVENTSIZE                   //Keep as the last element!
    };

    //initiate the vector with the basic handles
    vecEvents.clear();
    GetBasicEvents(vecEvents);

    while(bMainLoop)
    {
        //wait for event handle(s)
        dwResult = WaitForMultipleObjects(vecEvents.size(), &vecEvents[0], true, INFINITE);

        //New connection(s) made
        if(dwResult == (int)ACCEPTOR)
        {
            //Get the sockets for the new connections
            m_pAcceptor->GetOutData(vecSocks);

            //Create new connections
            for(unsigned int i = 0; i < vecSocks.size(); i++)
            {
                //Add a new connection
                CClientConnection Conn(vecSocks[i]);
                m_vecConnections.push_back(Conn);
                //Add event
                vecEvents.push_back(Conn.GetOutEvent());
            }
        }

        //Data from one of the connections
        if(dwResult >= (int)EVENTSIZE)
        {
            Inc::MSG Msg;
            //get received string data
            m_vecConnections[dwResult].GetOutData(vecData);

            //handle the data
            for(unsigned int i = 0; i < vecData.size(); i++)
            {
                //convert data into message
                if(Inc::StringToMessage(vecData[i], Msg) != Inc::SOK)
                    continue;
                //Add the socket to the sender information
                Msg.Sender.sock = vecSocks[dwResult];
                //Evaluate and delegate data and task
                EvaluateMessage(Msg);
            }
        }
    }
}
+1  A: 

Do not re-invent the wheel, use Boost.ASIO. It is well optimized utilizing kernel specific features of different operating systems, designed the way which makes client code architecture simple. There are a lot of examples and documentation, so you just cannot get it wrong.

Vlad Lazarenko