Main Page   Namespace List   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

server.cpp

Go to the documentation of this file.
00001 
00010 #include "sysconfig.h"
00011 #include "server.h"
00012 
00013 //##ModelId=3ED44BF102A6
00014 Server* Server::sInstance = 0;
00015 
00016 
00020 //##ModelId=3ED44BF10327
00021 //##ModelId=3ED44BF10330
00022 Server::Server() : mShutdown(false) {}
00023 
00027 //##ModelId=3ED44BF1032F
00028 Server::~Server() {
00029     ConnList::iterator i;
00030     for (i = mUsers.begin(); i != mUsers.end();) {
00031         delete (*i);
00032     }
00033 }
00034 
00040 //##ModelId=3ED44BF10311
00041 Server* Server::Instance() {
00042     if (sInstance == 0)
00043         sInstance = new Server;
00044     return sInstance;
00045 }
00046 
00050 //##ModelId=3ED44BF10325
00051 void Server::Destroy() {
00052     delete sInstance;
00053 }
00054 
00061 //##ModelId=3ED44BF10313
00062 bool Server::Boot(unsigned short port) {
00063     unsigned long flags = 1;
00064     int opt = 1;
00065     mTo.sin_family = AF_INET;
00066     mTo.sin_addr.s_addr = INADDR_ANY;
00067     mTo.sin_port = htons (port);
00068 
00069     // Get a socket for the server to listen on.
00070     mAcceptor = socket (AF_INET, SOCK_STREAM, 0);
00071     if (mAcceptor == INVALID_SOCKET) {
00072         cout << "ERROR-Server(socket):" << WSAGetLastError () << endl;
00073         return false;
00074     }
00075     // set it up to be non-blocking
00076     if (ioctlsocket (mAcceptor, FIONBIO, &flags) == SOCKET_ERROR) {
00077         cout << "ERROR-Server(ioctlsocket):" << WSAGetLastError () << endl;
00078         return false;
00079     }
00080     if (setsockopt (mAcceptor, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof (opt)) == SOCKET_ERROR) {
00081         cout << "ERROR-Server(setsockopt):" << WSAGetLastError () << endl;
00082         closesocket (mAcceptor);
00083         return false;
00084     }
00085     if (bind (mAcceptor, (struct sockaddr *) &mTo, sizeof (mTo)) == SOCKET_ERROR) {
00086         cout << "ERROR-Server(bind):" << WSAGetLastError () << endl;
00087         closesocket (mAcceptor);
00088         return false;
00089     }
00090     if (listen (mAcceptor, 5) == SOCKET_ERROR) {
00091         cout << "ERROR-Server(listen):" << WSAGetLastError () << endl;
00092         return false;
00093     }
00094     return true;
00095 }
00096 
00103 //##ModelId=3ED44BF1031C
00104 void Server::Run() {
00105     struct timeval timeout;
00106     timeout.tv_sec = 60;
00107     timeout.tv_usec = 0;
00108     ConnList::iterator i, curr;
00109 
00110     while (!mShutdown) {
00111         InitFDs();
00112         if (select(0, &mInputFDs, &mOutputFDs, NULL, &timeout) == SOCKET_ERROR) {
00113             cout << "ERROR-Server(select):" << WSAGetLastError () << endl;
00114             break;
00115         }
00116         Execute();
00117         if (FD_ISSET(mAcceptor, &mInputFDs)) {
00118             Connection * c = AcceptConnection();
00119             if (c) {
00120                 c->SendMsg("Welcome!\r\n");
00121                 mUsers.push_back(c);
00122             }
00123         }
00124         for (i = mUsers.begin(); i != mUsers.end(); i++) {
00125             if (FD_ISSET((*i)->GetSocket(), &mOutputFDs))
00126                 (*i)->HandleOutput();
00127             if (FD_ISSET((*i)->GetSocket(), &mInputFDs))
00128                 (*i)->HandleInput();
00129         }
00130         for (i = mUsers.begin(); i != mUsers.end();) {
00131             curr = i++;
00132             if ((*curr)->CanBeDisconnected()) {
00133                 (*curr)->Disconnect();
00134                 delete (*curr);
00135                 mUsers.erase(curr);
00136             }
00137         }
00138     }
00139     ShutdownServer();
00140 }
00141 
00148 //##ModelId=3ED44BF10344
00149 Connection* Server::AcceptConnection() {
00150     struct sockaddr_in from;
00151     Connection *conn;
00152     int fromlen = sizeof (from);
00153     SOCKET psock = accept (mAcceptor, (struct sockaddr *) & from, &fromlen);
00154     if (psock == INVALID_SOCKET) {
00155         return NULL;
00156     } else {
00157         unsigned long flags = 1;
00158         ioctlsocket (psock, FIONBIO, &flags);
00159         conn = new Connection(psock);
00160         return conn;
00161     }
00162 }
00163 
00174 //##ModelId=3ED44BF1034D
00175 void Server::InitFDs () {
00176     FD_ZERO (&mInputFDs);
00177     FD_ZERO (&mOutputFDs);
00178     FD_SET (mAcceptor, &mInputFDs);
00179     for (ConnList::iterator i = mUsers.begin(); i != mUsers.end(); i++) {
00180         FD_SET ((*i)->GetSocket(), &mInputFDs);
00181         FD_SET ((*i)->GetSocket(), &mOutputFDs);
00182     }
00183 }
00184 
00194 //##ModelId=3ED44BF1034E
00195 void Server::Execute() {
00196     ConnList::iterator i, o;
00197     string* msg;
00198     for (i = mUsers.begin(); i != mUsers.end(); i++) {
00199         while ((msg = (*i)->ReadMsg()) != NULL) {
00200             if (!msg->compare("@shutdown")) {
00201                 mShutdown = true;
00202                 for (o = mUsers.begin(); o != mUsers.end(); o++) {
00203                     (*o)->SendMsg("Shutting down..BYE.\r\n");
00204                 }
00205                 delete msg;
00206                 return ;
00207             }
00208             msg->append("\r\n");
00209             for (o = mUsers.begin(); o != mUsers.end(); o++) {
00210                 (*o)->SendMsg(*msg);
00211             }
00212             delete msg;
00213         }
00214     }
00215 }
00216 
00223 //##ModelId=3ED44BF10357
00224 void Server::ShutdownServer() {
00225     ConnList::iterator i, curr;
00226     for (i = mUsers.begin(); i != mUsers.end();) {
00227         curr = i++;
00228         (*curr)->Disconnect();
00229         delete (*curr);
00230         mUsers.erase(curr);
00231     }
00232     closesocket(mAcceptor);
00233 }
00234 

Generated on Mon Mar 29 22:38:41 2004 for Paradigm by doxygen1.2.17