SocketServer und MessageQueue



  • Hey Leute,

    ich schreib mir grad nen einfachen SocketServer. Der läuft in einem extra Thread und dieser Thread hat eine MessageQueue durch die er Daten mit andern Threads austauscht. Der Socket wartet mit Hilfe von select auf einkommende Verbindungen oder Daten von Clients. Als Timeout für select hab ich 1sec gewählt. Das Problem ist jetzt, dass solange select blockiert ja keine Messages abgearbeitet werden können. Kann ich irgendwie einen eigenen FileDescriptor anlegen, den ich dann beim select mit überwachen kann? So könnte ich das select beim eintreffen neuer Messages wieder aufwecken. So sieht das zur Zeit aus:

    int err;
        fd_set tmpFdSet;
        map<int, SocketConnection*>::iterator i;
        struct timeval timeout;
        try
        {
            openSocket();
            updateFileHandleSet();
    
            while (!isTerminated())
            {
                tmpFdSet = this->_fileHandleSet;
                timeout = TimeVal::getCurrentTime(SOCKET_SERVER_CYCLE_TIMEOUT);
                if ((err = select(this->_maxFileHandle+1, &tmpFdSet, NULL, NULL, &timeout)) < 0)
                {
                    ostringstream ss;
                    ss << "error while waiting (select) for server file descriptor: " << err;
                    throw ETcpSocketModule(ss.str());
                }                
    
                if (FD_ISSET(this->_serverFileHandle, &tmpFdSet))
                    acceptConnection();
    
                i = _connections.begin();
                while(i != _connections.end())
                {
                    if (FD_ISSET((*i).first, &tmpFdSet) && !(*i).second->progress())
                        i = _connections.erase(i);
                    else
                        i++;
                }
    
                progressMessages();
            }
        }
        catch(Exception ex)
        {
            this->_owner->log("error while executing server socket thread:\n", ex);
        }
    

    Bin dankbar für jegliche Art von Kommentaren.

    MfG Bergmann.



  • Kannst Du nicht den Serversocket in einem eigenen nur dafür vorgesehenen Thread laufen lassen? Dann kann der messageverarbeitende Thread verzögerungsfrei seine Messages abarbeiten.
    Wenn der Serversocket etwas zu vermelden hat wie eingehende Verbindungen, oder Daten, schickt er dem messageverarbeitenden Thread eine entsprechende Message, die dieser dann verarbeitet.



  • Hey,

    das ist mir auch schon in den Sinn gekommen, das wäre sozusagen die alternativ-Lösung. Ich wollt aber erstmal nachfragen ob es evtl. auch mit einem Thread sinnvoll geht...

    MfG Bergmann.



  • Wenn es ein Fenster-Thread wäre, gäbe es wohl
    http://msdn.microsoft.com/de-de/library/windows/desktop/ms741540(v=vs.85).aspx
    dafür.



  • Einfach nicht select() benutzen. Wenn du schon auf schlecht skalierende Server stehst, dann nimm WaitForMultipleObjects() und WSAEventSelect(), dann kannst du beliebige EVENT-Objekte gleichzeitig überwachen (also auch eins für deine Msg-Queue). Oder du nimmst gleich Boost, was dir schön Overlapped I/O mit I/O-Completionports für beste Performance liefert, bugfrei und plattformunabhängig ist.



  • Hey,

    vlt sollte ich doch etwas weiter ausholen.
    Das ganze Projekt soll am Ende auf einem embedded System laufen. Der Server soll also am Ende keine hunderte von Verbindungen managen, sondern dient nur zur Kommunikation zwischen dem Gerät und einigen wenigen Clients (worst-case ca. 5). Da das embedded System bei weitem nicht so leistungsstark ist wie ein normaler PC, läuft das mit der Skalierung vom Server hier auch ein wenig anders, deshalb auch nur ein Thread für den kompletten Server. Auf dem Gerät kommt Linux zum Einsatz, also wird das mit den WinAPI Funktionen leider nichts. An boost hab ich auch schon gedacht, aber da hatte ich bedenken, das es evlt wieder zu overkill für das kleine System ist.

    MfG Bergmann.


Anmelden zum Antworten