Server.cpp
上传用户:jxpjxmjjw
上传日期:2009-12-07
资源大小:5877k
文件大小:5k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. // Copyright (C) 2004 Team Python
  2. //  
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. // 
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. // GNU General Public License for more details.
  12. // 
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software 
  15. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. #include "Server.h"
  17. #include "RealmListSrv.h"
  18. #include "Network.h"
  19. #include "Log.h"
  20. #include "Threads.h"
  21. #include "Client.h"
  22. #include "Sockets.h"
  23. #include "math.h"
  24. #include <time.h>
  25. #include "Timer.h"
  26. #if PLATFORM == PLATFORM_WIN32
  27. #include <windows.h>
  28. #else
  29. #include <unistd.h>
  30. #include <sys/select.h>
  31. #endif
  32. #include <stdlib.h>
  33. #include <iostream>
  34. void Server::Initialise(unsigned int port, char* type) {
  35.   mNetwork = Network::getSingletonPtr( );
  36.   mPort = port;
  37.   mType = type;
  38. }
  39. void Server::Start( ) {
  40.   if( !mActive ) {
  41.     mActive = true;
  42.     mStop = false;
  43. eventStart( );
  44.     Threads::getSingleton( ).Fork( MainLoop, this, Threads::TP_HIGHER );
  45. mLastTicks = clock( );
  46. mLastTime = (float)mLastTicks / CLOCKS_PER_SEC;
  47.     //_beginthread( threadListen, 0, this );
  48.   }
  49. }
  50. void Server::Stop( ) {
  51.   mStop = true;
  52.   while( mActive );
  53.   eventStop( );
  54. }
  55. THREADCALL Server::MainLoop( void * myServer ) {
  56.   NetworkInterface * listener = Network::getSingleton( ).createWorldListener( ((Server *) myServer)->mPort );
  57.   nlink_server * cptr;
  58.   nlink * tCptr;
  59.   cptr = new nlink_server;
  60.   cptr->hdr.type = RSERVER;
  61.   cptr->hdr.flags = 0;
  62.   cptr->hdr.fd = listener->getSocketID();
  63.   ((Server *)myServer)->nlink_init();
  64.   ((Server *)myServer)->nlink_insert((nlink *)cptr);
  65.   int res;
  66.   struct timeval selectTimeout;
  67.   selectTimeout.tv_sec = 0;
  68.   selectTimeout.tv_usec = 100000;
  69.   int nfds;
  70.   fd_set rfds;
  71.   fd_set wfds;
  72.   fd_set efds;
  73.   unsigned short revents;
  74.   //float timeDif; 
  75.   //uint32 newTicks;
  76.   uint32 realCurrTime, realPrevTime, realTimeDiff;
  77.   realPrevTime = getMSTime();
  78.   realTimeDiff = 0;
  79.   while( ! ( (Server *)myServer )->mStop ) {
  80. realCurrTime = getMSTime();
  81. if (realPrevTime > realCurrTime) { //uint32 exceeded
  82. realPrevTime = 0;
  83. }
  84. realTimeDiff = realCurrTime - realPrevTime;
  85.     ((Server *)myServer)->Update( realTimeDiff );
  86. realPrevTime = realCurrTime;
  87.     nfds = 0;
  88. FD_ZERO(&rfds);
  89. FD_ZERO(&wfds);
  90. FD_ZERO(&efds);
  91. tCptr = ((Server *)myServer)->getHead();
  92. while(tCptr)
  93. {
  94. if (tCptr->flags & CF_DEAD)
  95. {
  96. #if PLATFORM == PLATFORM_WIN32
  97. closesocket(tCptr->fd);
  98. #else
  99. close(tCptr->fd);
  100. #endif
  101. tCptr = ((Server *)myServer)->nlink_remove((nlink *)tCptr);
  102. continue;
  103. }
  104. switch(tCptr->type)
  105. {
  106. case RSERVER:
  107. {
  108. FD_SET(tCptr->fd, &rfds);
  109. if (tCptr->fd >= nfds)
  110. nfds = tCptr->fd + 1;
  111. break;
  112. }
  113. case RCLIENT:
  114. {
  115. FD_SET(tCptr->fd, &rfds);
  116. if (tCptr->fd >= nfds)
  117. nfds = tCptr->fd + 1;
  118. //printf("Write Buffer: %dn",(((nlink_client *)tCptr)->pClient)->getNetwork()->getSendqLen());
  119. if ( (((nlink_client *)tCptr)->pClient)->getNetwork()->getSendqLen()  > 0)
  120. {
  121. FD_SET(tCptr->fd, &wfds);
  122. if (tCptr->fd >= nfds)
  123. nfds = tCptr->fd + 1;
  124. }
  125. break;
  126. }
  127. }
  128. tCptr = tCptr->next;
  129. }
  130. selectTimeout.tv_sec = 0;
  131.     selectTimeout.tv_usec = 100000; // 100ms timeout
  132. res = select(nfds, &rfds, &wfds, &efds, &selectTimeout);
  133. if (res == 0)
  134. continue;
  135. if (res == -1)
  136. break;
  137. for(tCptr = ((Server *)myServer)->getHead() ; tCptr; tCptr = tCptr->next)
  138. {
  139. if (tCptr->flags & CF_DEAD)
  140. continue;
  141. revents = 0;
  142. if(FD_ISSET(tCptr->fd, &rfds))
  143. revents |= PF_READ;
  144. if(FD_ISSET(tCptr->fd, &wfds))
  145. revents |= PF_WRITE;
  146. if(FD_ISSET(tCptr->fd, &efds))
  147. revents |= PF_EXCEPT;
  148. if (revents) 
  149. {
  150. if (tCptr->type == RSERVER)
  151. {
  152. ((Server *)myServer)->server_sockevent((nlink_server *)tCptr, revents , listener);
  153. }
  154. else if (tCptr->type == RCLIENT)
  155. {
  156. ((Server *)myServer)->client_sockevent((nlink_client *)tCptr, revents);
  157. }
  158. }
  159. }
  160.   }
  161.   ((Server *)myServer)->mActive = false;
  162.   ENDTHREAD
  163. }
  164. void Server::server_sockevent( nlink_server *cptr, uint16 revents, void *myNet ) {
  165. NetworkInterface * client;
  166. struct nlink_client *ncptr;
  167. if(revents & PF_READ)
  168. {
  169. client = ( ( NetworkInterface * ) myNet )->getConnection( );
  170. if (!client) 
  171. return;
  172. uint32 nonblockingstate = true;
  173. IOCTL_SOCKET( client->getSocketID(), IOCTL_NOBLOCK, &nonblockingstate );
  174. ncptr = new nlink_client;
  175. if(ncptr == NULL)
  176. return;
  177. memset(ncptr, 0, sizeof(*ncptr));
  178. ncptr->hdr.type = RCLIENT;
  179. ncptr->hdr.fd = client->getSocketID();
  180. nlink_insert((struct nlink *)ncptr);
  181. Client *pClient = new Client();
  182. pClient->BindNI(client);
  183. mClients.insert(pClient);
  184. }
  185. }