Page principale | Liste alphabétique | Liste des classes | Liste des fichiers | Membres de classe | Membres de fichier | Pages associées

NetServer.cpp

Aller à la documentation de ce fichier.
00001 /*! \file NetServer.cpp
00002     \brief Systeme serveur.
00003 
00004     Serveur multitache.
00005 
00006     \author     aerith (http://aerith.fr)
00007     \version    2.0
00008     \date       30/03/2008
00009 */
00010 
00011 #include    "NetServer.h"
00012 
00013 NetServer::NetServer(const char *pKeyFile, const char *pCertifFile)
00014 {
00015     conInfo     = NULL;
00016     limit       = NET_LIMIT;
00017     sslCTX      = NULL;
00018     crypt       = NET_T_NORMAL;
00019 
00020     if(pKeyFile && pCertifFile)
00021     {
00022         SSL_METHOD  *sslMethode;
00023 
00024         SSL_library_init();
00025         SSL_load_error_strings();
00026         sslMethode = SSLv23_server_method();
00027 
00028         sslCTX = SSL_CTX_new(sslMethode);
00029         if(!sslCTX)
00030             throw ERROR_C_SSLCTXINIT;
00031 
00032         if(SSL_CTX_use_PrivateKey_file(sslCTX, pKeyFile, SSL_FILETYPE_PEM) < 1)
00033             throw ERROR_C_SSLKEY;
00034 
00035         if(SSL_CTX_use_certificate_file(sslCTX, pCertifFile, SSL_FILETYPE_PEM) < 1)
00036             throw ERROR_C_SSLCERTIF;
00037 
00038         if(SSL_CTX_check_private_key(sslCTX) < 1)
00039             throw ERROR_C_SSLCHECK;
00040 
00041         keyFile = pKeyFile;
00042         certifFile = pCertifFile;
00043 
00044         crypt = NET_T_SSL;
00045     }
00046 }
00047 
00048 NetServer::~NetServer()
00049 {
00050     Stop();
00051 }
00052 
00053 void    ThreadWaitClient(NetServer *pServeur)
00054 {
00055     pServeur->WaitClient();
00056 }
00057 
00058 void    ThreadGarbageClient(NetServer *pServeur)
00059 {
00060     pServeur->GarbageClient();
00061 }
00062 
00063 void    NetServer::Start(unsigned int iPort, ROUTINE pRoutine, unsigned int iLimit)
00064 {
00065     BEGIN
00066 
00067     if(!conInfo)
00068         throw ERROR_C_ALREADY_START;
00069 
00070     conInfo = new NetConnect(crypt);
00071     conInfo->port = iPort;
00072 
00073     limit = iLimit;
00074     routineClient = pRoutine;
00075 
00076     if(SocketLoad())
00077         throw ERROR_C_LOAD_DLL;
00078 
00079     conInfo->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00080     if(conInfo->sock < 0)
00081         throw ERROR_C_INIT_CONNECT;
00082 
00083     memset(&conInfo->sockName, 0, sizeof(conInfo->sockName));
00084     conInfo->sockName.sin_port = htons(conInfo->port);
00085     conInfo->sockName.sin_family = AF_INET;
00086     conInfo->sockName.sin_addr.s_addr = INADDR_ANY;
00087 
00088     if(bind(conInfo->sock,(struct sockaddr*)&conInfo->sockName, sizeof(conInfo->sockName)))
00089         throw ERROR_C_BIND_CONNECT;
00090 
00091     if(listen(conInfo->sock, limit))
00092         throw ERROR_C_LISTEN;
00093 
00094     if(ThreadStart(&threadGarbage, (ROUTINE)ThreadGarbageClient, this))
00095         throw ERROR_C_THREAD;
00096 
00097     if(ThreadStart(&threadClients, (ROUTINE)ThreadWaitClient, this))
00098         throw ERROR_C_THREAD;
00099 
00100     ENDBEGIN
00101 }
00102 
00103 void    NetServer::Stop()
00104 {
00105     if(conInfo)
00106     {
00107         delete conInfo;
00108         conInfo = NULL;
00109     }
00110 
00111     ThreadWait(&threadClients);
00112 
00113     while(clients.size())
00114         KillClientNo(0);
00115     clients.clear();
00116 
00117     ThreadWait(&threadGarbage);
00118 }
00119 
00120 void    NetServer::GarbageClient()
00121 {
00122     unsigned int    i;
00123     BEGIN
00124 
00125     do
00126     {
00127         for(i = 0; i < clients.size(); i++)
00128         {
00129             if(!clients[i]->ip.size())
00130             {
00131                 SocketClose(clients[i]->sock);
00132 
00133                 if(clients[i]->crypt == NET_T_SSL)
00134                 {
00135                     SSL_shutdown(clients[i]->sslFD);
00136                     SSL_free(clients[i]->sslFD);
00137                 }
00138 
00139                 ThreadWait(&(clients[i]->thread));
00140 
00141                 clients.erase(clients.begin() + i);
00142             }
00143         }
00144         TempWait(NET_GARBAGE);
00145     }
00146     while(conInfo);
00147 
00148     ENDBEGINPRINT
00149 
00150     ThreadExit(0);
00151 }
00152 
00153 void    NetServer::WaitClient()
00154 {
00155     unsigned int    lenght = 0, err = 0;
00156     BEGIN
00157 
00158     while(conInfo)
00159     {
00160         if(clients.size() < limit)
00161         {
00162             err = 0;
00163             clients.push_back(new NetConnect(crypt));
00164             lenght = sizeof(clients.back()->sockName);
00165             clients.back()->sock = accept(conInfo->sock, (struct sockaddr*)&clients.back()->sockName, (socklen_t *)&lenght);
00166 
00167             if(clients.back()->sock != -1)
00168             {
00169                 unsigned char *pIp = (unsigned char *)&clients.back()->sockName.sin_addr.s_addr;
00170                 clients.back()->ip = ItoA(pIp[0]);
00171                 clients.back()->ip += ItoA(pIp[1]);
00172                 clients.back()->ip += ItoA(pIp[2]);
00173                 clients.back()->ip += ItoA(pIp[3]);
00174 
00175                 if(crypt == NET_T_SSL)
00176                 {
00177                     clients.back()->sslFD = SSL_new(sslCTX);
00178                     if( (!clients.back()->sslFD) ||
00179                         (SSL_set_fd(clients.back()->sslFD, clients.back()->sock) < 1) ||
00180                         (SSL_accept(clients.back()->sslFD) < 1)
00181                     )
00182                     {
00183                         SSL_shutdown(clients.back()->sslFD);
00184                         SSL_free(clients.back()->sslFD);
00185                         err = 1;
00186                     }
00187                 }
00188 
00189                 if(!err)
00190                     if(!ThreadStart(&clients.back()->thread, routineClient, (PARAMETRE)clients.back()))
00191                         err = 1;
00192             }
00193             else
00194                 err = 1;
00195 
00196             if(err)
00197                 clients.erase(clients.begin() + clients.size());
00198         }
00199         else
00200             TempWait(NET_WAIT_FULL);
00201     }
00202 
00203     ENDBEGINPRINT
00204 
00205     ThreadExit(0);
00206 }
00207 
00208 void    NetServer::KillClient(unsigned int iId)
00209 {
00210     for(unsigned int i = 0; i < clients.size(); i++)
00211         if(clients[i]->GetId() == iId)
00212             clients[i]->ip = "";
00213 }
00214 
00215 void    NetServer::KillClientNo(unsigned int iNo)
00216 {
00217     if(iNo < clients.size())
00218         clients[iNo]->ip = "";
00219 }
00220 

Généré le Thu Jun 12 09:12:30 2008 pour A.I.F. par  doxygen 1.3.9.1