00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <net/NetServerTCP3.h>
00022 #include <net/NetMessagePool.h>
00023 #include <net/NetOptions.h>
00024 #include <common/Logger.h>
00025 #include <common/Clock.h>
00026 #include <limits.h>
00027
00028 NetServerTCP3::NetServerTCP3() :
00029 serverDestinationId_(UINT_MAX), nextDestinationId_(1),
00030 sendRecvThread_(0),
00031 serverSock_(0), serverSockSet_(0),
00032 stopped_(false)
00033 {
00034 NetOptions::instance()->readOptionsFromFile();
00035 NetOptions::instance()->writeOptionsToFile();
00036
00037 serverSockSet_ = SDLNet_AllocSocketSet(1);
00038 }
00039
00040 NetServerTCP3::~NetServerTCP3()
00041 {
00042 SDLNet_FreeSocketSet(serverSockSet_);
00043 serverSockSet_ = 0;
00044 }
00045
00046 bool NetServerTCP3::started()
00047 {
00048
00049 return (sendRecvThread_ != 0);
00050 }
00051
00052 bool NetServerTCP3::connect(const char *hostName, int portNo)
00053 {
00054 if(SDLNet_Init()==-1)
00055 {
00056 return false;
00057 }
00058
00059
00060 IPaddress serverAddress;
00061 if (SDLNet_ResolveHost(&serverAddress, hostName, portNo) != 0)
00062 {
00063 Logger::log(S3D::formatStringBuffer("NetServerTCP3: Failed to resolve host %s:%i",
00064 hostName, portNo));
00065 return false;
00066 }
00067
00068
00069 stop();
00070
00071
00072 TCPsocket clientSock = SDLNet_TCP_Open(&serverAddress);
00073 if (!clientSock)
00074 {
00075 Logger::log(S3D::formatStringBuffer("NetServerTCP3: Failed to open client socket : %s",
00076 SDLNet_GetError()));
00077 return false;
00078 }
00079
00080
00081 serverDestinationId_ = addDestination(clientSock);
00082
00083
00084 if (!startProcessing()) return false;
00085
00086 return true;
00087 }
00088
00089 bool NetServerTCP3::start(int portNo)
00090 {
00091 if(SDLNet_Init()==-1)
00092 {
00093 return false;
00094 }
00095
00096
00097 stop();
00098
00099
00100 IPaddress localip;
00101 if(SDLNet_ResolveHost(&localip, NULL, portNo)==-1)
00102 {
00103 return false;
00104 }
00105
00106
00107
00108
00109 serverSock_ = SDLNet_TCP_Open(&localip);
00110 if (!serverSock_)
00111 {
00112 Logger::log(S3D::formatStringBuffer("NetServerTCP3: Failed to open server socket %i", portNo));
00113 return false;
00114 }
00115 SDLNet_TCP_AddSocket(serverSockSet_, serverSock_);
00116
00117
00118 if (!startProcessing()) return false;
00119
00120 return true;
00121 }
00122
00123 void NetServerTCP3::stop()
00124 {
00125 if (started())
00126 {
00127 disconnectAllClients();
00128 while (started()) SDL_Delay(100);
00129 }
00130 }
00131
00132 bool NetServerTCP3::startProcessing()
00133 {
00134
00135 DIALOG_ASSERT(!sendRecvThread_);
00136
00137
00138 outgoingMessageHandler_.setMessageHandler(this);
00139
00140
00141 sendRecvThread_ = SDL_CreateThread(
00142 NetServerTCP3::sendRecvThreadFunc, (void *) this);
00143 if (sendRecvThread_ == 0)
00144 {
00145 Logger::log(S3D::formatStringBuffer("NetServerTCP3: Failed to create NetServerTCP3 thread"));
00146 return false;
00147 }
00148
00149 return true;
00150 }
00151
00152 int NetServerTCP3::sendRecvThreadFunc(void *c)
00153 {
00154
00155 NetServerTCP3 *th = (NetServerTCP3*) c;
00156 th->actualSendRecvFunc();
00157
00158 th->sendRecvThread_ = 0;
00159 Logger::log(S3D::formatStringBuffer("NetServerTCP3: shutdown"));
00160 return 0;
00161 }
00162
00163 void NetServerTCP3::actualSendRecvFunc()
00164 {
00165 float timeDiff;
00166 stopped_ = false;
00167 Clock netClock;
00168 while(!stopped_)
00169 {
00170
00171 checkClients();
00172 timeDiff = netClock.getTimeDifference();
00173 if (timeDiff > 1.0f)
00174 {
00175 Logger::log(S3D::formatStringBuffer(
00176 "NetServerTCP3: checkClients took %.2f seconds",
00177 timeDiff));
00178 }
00179
00180
00181 checkNewConnections();
00182 timeDiff = netClock.getTimeDifference();
00183 if (timeDiff > 1.0f)
00184 {
00185 Logger::log(S3D::formatStringBuffer(
00186 "NetServerTCP3: checkNewConnections took %.2f seconds",
00187 timeDiff));
00188 }
00189
00190
00191 SDL_Delay(10);
00192 netClock.getTimeDifference();
00193
00194
00195 outgoingMessageHandler_.processMessages();
00196 timeDiff = netClock.getTimeDifference();
00197 if (timeDiff > 1.0f)
00198 {
00199 Logger::log(S3D::formatStringBuffer(
00200 "NetServerTCP3: processMessages took %.2f seconds",
00201 timeDiff));
00202 }
00203 }
00204
00205 if (serverSock_) SDLNet_TCP_Close(serverSock_);
00206 serverSock_ = 0;
00207 }
00208
00209 void NetServerTCP3::checkNewConnections()
00210 {
00211 if (!serverSock_) return;
00212
00213 int numready = SDLNet_CheckSockets(serverSockSet_, 10);
00214 if (numready == -1) return;
00215 if (numready == 0) return;
00216
00217 if(SDLNet_SocketReady(serverSock_))
00218 {
00219 TCPsocket clientSock = SDLNet_TCP_Accept(serverSock_);
00220 if (clientSock)
00221 {
00222
00223 addDestination(clientSock);
00224 }
00225 }
00226 }
00227
00228 void NetServerTCP3::checkClients()
00229 {
00230
00231 std::map<unsigned int, NetServerTCP3Destination *>::iterator itor;
00232 for (itor = destinations_.begin();
00233 itor != destinations_.end();
00234 itor++)
00235 {
00236 NetServerTCP3Destination *destination = itor->second;
00237 if (destination->anyFinished())
00238 {
00239 destroyDestination(itor->first, NetMessage::UserDisconnect);
00240 break;
00241 }
00242 }
00243
00244
00245 if (finishedDestinations_.empty()) return;
00246
00247 NetServerTCP3Destination *destination = finishedDestinations_.front();
00248 if (destination->allFinished())
00249 {
00250 delete destination;
00251 finishedDestinations_.pop_front();
00252 }
00253 }
00254
00255 void NetServerTCP3::processMessage(NetMessage &message)
00256 {
00257
00258
00259
00260 if (message.getMessageType() == NetMessage::DisconnectAllMessage)
00261 {
00262
00263 while (!destinations_.empty())
00264 {
00265
00266 std::map<unsigned int, NetServerTCP3Destination *>::iterator itor =
00267 destinations_.begin();
00268 unsigned int destinationId = (*itor).first;
00269 NetServerTCP3Destination *destination = (*itor).second;
00270
00271
00272 destroyDestination(destinationId, NetMessage::KickDisconnect);
00273 }
00274
00275 stopped_ = true;
00276 return;
00277 }
00278
00279
00280 std::map<unsigned int, NetServerTCP3Destination *>::iterator itor =
00281 destinations_.find(message.getDestinationId());
00282 if (itor == destinations_.end())
00283 {
00284 return;
00285 }
00286
00287 NetServerTCP3Destination *destination = (*itor).second;
00288 if (message.getMessageType() == NetMessage::DisconnectMessage)
00289 {
00290
00291 destroyDestination(message.getDestinationId(), NetMessage::KickDisconnect);
00292 }
00293 else
00294 {
00295
00296 NetMessage *newMessage = NetMessagePool::instance()->getFromPool(
00297 message.getMessageType(), message.getDestinationId(),
00298 message.getIpAddress(), message.getFlags());
00299 newMessage->getBuffer().allocate(message.getBuffer().getBufferUsed());
00300 memcpy(newMessage->getBuffer().getBuffer(),
00301 message.getBuffer().getBuffer(),
00302 message.getBuffer().getBufferUsed());
00303 newMessage->getBuffer().setBufferUsed(message.getBuffer().getBufferUsed());
00304
00305 destination->sendMessage(newMessage);
00306 }
00307 }
00308
00309 void NetServerTCP3::disconnectAllClients()
00310 {
00311
00312 NetMessage *message = NetMessagePool::instance()->
00313 getFromPool(NetMessage::DisconnectAllMessage, 0, 0);
00314
00315
00316 outgoingMessageHandler_.addMessage(message);
00317 }
00318
00319 void NetServerTCP3::disconnectClient(unsigned int destination)
00320 {
00321
00322 NetMessage *message = NetMessagePool::instance()->
00323 getFromPool(NetMessage::DisconnectMessage, destination, 0);
00324
00325
00326 outgoingMessageHandler_.addMessage(message);
00327 }
00328
00329 void NetServerTCP3::sendMessageServer(NetBuffer &buffer,
00330 unsigned int flags)
00331 {
00332
00333 sendMessageDest(buffer, serverDestinationId_, flags);
00334 }
00335
00336 void NetServerTCP3::sendMessageDest(NetBuffer &buffer,
00337 unsigned int destination, unsigned int flags)
00338 {
00339
00340 NetMessage *message = NetMessagePool::instance()->
00341 getFromPool(NetMessage::BufferMessage,
00342 destination, 0, flags);
00343
00344
00345 message->getBuffer().allocate(buffer.getBufferUsed());
00346 memcpy(message->getBuffer().getBuffer(),
00347 buffer.getBuffer(), buffer.getBufferUsed());
00348 message->getBuffer().setBufferUsed(buffer.getBufferUsed());
00349
00350
00351 outgoingMessageHandler_.addMessage(message);
00352 }
00353
00354 int NetServerTCP3::processMessages()
00355 {
00356
00357 return incomingMessageHandler_.processMessages();
00358 }
00359
00360 void NetServerTCP3::setMessageHandler(NetMessageHandlerI *handler)
00361 {
00362
00363 incomingMessageHandler_.setMessageHandler(handler);
00364 }
00365
00366 void NetServerTCP3::destroyDestination(unsigned int destinationId,
00367 NetMessage::DisconnectFlags type)
00368 {
00369
00370 std::map<unsigned int, NetServerTCP3Destination *>::iterator itor =
00371 destinations_.find(destinationId);
00372 if (itor == destinations_.end())
00373 {
00374 return;
00375 }
00376
00377 if (serverDestinationId_ == destinationId)
00378 {
00379 stopped_ = true;
00380 serverDestinationId_ = UINT_MAX;
00381 }
00382
00383 NetServerTCP3Destination *destination = (*itor).second;
00384
00385
00386 NetMessage *message = NetMessagePool::instance()->
00387 getFromPool(NetMessage::DisconnectMessage,
00388 destinationId, destination->getIpAddress());
00389 message->setFlags((unsigned int) type);
00390
00391 destinations_.erase(itor);
00392 destination->printStats();
00393 destination->close();
00394 finishedDestinations_.push_back(destination);
00395
00396
00397 incomingMessageHandler_.addMessage(message);
00398 }
00399
00400 unsigned int NetServerTCP3::addDestination(TCPsocket &socket)
00401 {
00402 NetInterface::getConnects() ++;
00403
00404
00405 do {
00406 nextDestinationId_++;
00407 } while (nextDestinationId_ == 0 || nextDestinationId_ == UINT_MAX);
00408 unsigned int destinationId = nextDestinationId_;
00409
00410
00411 NetServerTCP3Destination *destination =
00412 new NetServerTCP3Destination(
00413 &incomingMessageHandler_, socket, destinationId);
00414 destinations_[destinationId] = destination;
00415
00416
00417 NetMessage *message = NetMessagePool::instance()->
00418 getFromPool(NetMessage::ConnectMessage,
00419 destinationId, destination->getIpAddress());
00420 incomingMessageHandler_.addMessage(message);
00421
00422
00423 return destinationId;
00424 }