00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <net/NetServerTCP2.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 NetServerTCP2::NetServerTCP2() :
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 NetServerTCP2::~NetServerTCP2()
00041 {
00042 SDLNet_FreeSocketSet(serverSockSet_);
00043 serverSockSet_ = 0;
00044 }
00045
00046 bool NetServerTCP2::started()
00047 {
00048
00049 return (sendRecvThread_ != 0);
00050 }
00051
00052 bool NetServerTCP2::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("NetServerTCP2: 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("NetServerTCP2: 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 NetServerTCP2::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("NetServerTCP2: 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 NetServerTCP2::stop()
00124 {
00125 if (started())
00126 {
00127 disconnectAllClients();
00128 while (started()) SDL_Delay(100);
00129 }
00130 }
00131
00132 bool NetServerTCP2::startProcessing()
00133 {
00134
00135 DIALOG_ASSERT(!sendRecvThread_);
00136
00137
00138 outgoingMessageHandler_.setMessageHandler(this);
00139
00140
00141 sendRecvThread_ = SDL_CreateThread(
00142 NetServerTCP2::sendRecvThreadFunc, (void *) this);
00143 if (sendRecvThread_ == 0)
00144 {
00145 Logger::log(S3D::formatStringBuffer("NetServerTCP2: Failed to create NetServerTCP2 thread"));
00146 return false;
00147 }
00148
00149 return true;
00150 }
00151
00152 int NetServerTCP2::sendRecvThreadFunc(void *c)
00153 {
00154
00155 NetServerTCP2 *th = (NetServerTCP2*) c;
00156 th->actualSendRecvFunc();
00157
00158 th->sendRecvThread_ = 0;
00159 Logger::log(S3D::formatStringBuffer("NetServerTCP2: shutdown"));
00160 return 0;
00161 }
00162
00163 void NetServerTCP2::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 "NetServerTCP2: 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 "NetServerTCP2: 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 "NetServerTCP2: processMessages took %.2f seconds",
00201 timeDiff));
00202 }
00203 }
00204
00205 if (serverSock_) SDLNet_TCP_Close(serverSock_);
00206 serverSock_ = 0;
00207 }
00208
00209 void NetServerTCP2::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 NetServerTCP2::checkClients()
00229 {
00230
00231 std::map<unsigned int, NetServerTCP2Destination *>::iterator itor;
00232 for (itor = destinations_.begin();
00233 itor != destinations_.end();
00234 itor++)
00235 {
00236 NetServerTCP2Destination *destination = itor->second;
00237 if (destination->finished())
00238 {
00239 destroyDestination(itor->first, NetMessage::UserDisconnect);
00240 break;
00241 }
00242 }
00243
00244
00245 if (finishedDestinations_.empty()) return;
00246
00247 NetServerTCP2Destination *destination = finishedDestinations_.front();
00248 if (destination->finished())
00249 {
00250 delete destination;
00251 finishedDestinations_.pop_front();
00252 }
00253 }
00254
00255 void NetServerTCP2::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, NetServerTCP2Destination *>::iterator itor =
00267 destinations_.begin();
00268 unsigned int destinationId = (*itor).first;
00269 NetServerTCP2Destination *destination = (*itor).second;
00270
00271
00272
00273 destroyDestination(destinationId, NetMessage::KickDisconnect);
00274 }
00275
00276 stopped_ = true;
00277 return;
00278 }
00279
00280
00281 std::map<unsigned int, NetServerTCP2Destination *>::iterator itor =
00282 destinations_.find(message.getDestinationId());
00283 if (itor == destinations_.end())
00284 {
00285
00286
00287
00288 return;
00289 }
00290
00291 NetServerTCP2Destination *destination = (*itor).second;
00292 if (message.getMessageType() == NetMessage::DisconnectMessage)
00293 {
00294
00295
00296
00297 destroyDestination(message.getDestinationId(), NetMessage::KickDisconnect);
00298 }
00299 else
00300 {
00301
00302 NetMessage *newMessage = NetMessagePool::instance()->getFromPool(
00303 message.getMessageType(), message.getDestinationId(),
00304 message.getIpAddress(), message.getFlags());
00305 newMessage->getBuffer().allocate(message.getBuffer().getBufferUsed());
00306 memcpy(newMessage->getBuffer().getBuffer(),
00307 message.getBuffer().getBuffer(),
00308 message.getBuffer().getBufferUsed());
00309 newMessage->getBuffer().setBufferUsed(message.getBuffer().getBufferUsed());
00310
00311 destination->addMessage(newMessage);
00312 }
00313 }
00314
00315 void NetServerTCP2::disconnectAllClients()
00316 {
00317
00318 NetMessage *message = NetMessagePool::instance()->
00319 getFromPool(NetMessage::DisconnectAllMessage, 0, 0);
00320
00321
00322 outgoingMessageHandler_.addMessage(message);
00323 }
00324
00325 void NetServerTCP2::disconnectClient(unsigned int destination)
00326 {
00327
00328 NetMessage *message = NetMessagePool::instance()->
00329 getFromPool(NetMessage::DisconnectMessage, destination, 0);
00330
00331
00332 outgoingMessageHandler_.addMessage(message);
00333 }
00334
00335 void NetServerTCP2::sendMessageServer(NetBuffer &buffer,
00336 unsigned int flags)
00337 {
00338
00339 sendMessageDest(buffer, serverDestinationId_, flags);
00340 }
00341
00342 void NetServerTCP2::sendMessageDest(NetBuffer &buffer,
00343 unsigned int destination, unsigned int flags)
00344 {
00345
00346 NetMessage *message = NetMessagePool::instance()->
00347 getFromPool(NetMessage::BufferMessage,
00348 destination, 0, flags);
00349
00350
00351 message->getBuffer().allocate(buffer.getBufferUsed());
00352 memcpy(message->getBuffer().getBuffer(),
00353 buffer.getBuffer(), buffer.getBufferUsed());
00354 message->getBuffer().setBufferUsed(buffer.getBufferUsed());
00355
00356
00357 outgoingMessageHandler_.addMessage(message);
00358 }
00359
00360 int NetServerTCP2::processMessages()
00361 {
00362
00363 return incomingMessageHandler_.processMessages();
00364 }
00365
00366 void NetServerTCP2::setMessageHandler(NetMessageHandlerI *handler)
00367 {
00368
00369 incomingMessageHandler_.setMessageHandler(handler);
00370 }
00371
00372 void NetServerTCP2::destroyDestination(unsigned int destinationId,
00373 NetMessage::DisconnectFlags type)
00374 {
00375
00376 std::map<unsigned int, NetServerTCP2Destination *>::iterator itor =
00377 destinations_.find(destinationId);
00378 if (itor == destinations_.end())
00379 {
00380 return;
00381 }
00382
00383 if (serverDestinationId_ == destinationId)
00384 {
00385 stopped_ = true;
00386 serverDestinationId_ = UINT_MAX;
00387 }
00388
00389 NetServerTCP2Destination *destination = (*itor).second;
00390
00391
00392 NetMessage *message = NetMessagePool::instance()->
00393 getFromPool(NetMessage::DisconnectMessage,
00394 destinationId, destination->getIpAddress());
00395 message->setFlags((unsigned int) type);
00396
00397 destinations_.erase(itor);
00398 destination->printStats(destinationId);
00399 destination->stop();
00400 finishedDestinations_.push_back(destination);
00401
00402
00403 incomingMessageHandler_.addMessage(message);
00404 }
00405
00406 unsigned int NetServerTCP2::addDestination(TCPsocket &socket)
00407 {
00408 NetInterface::getConnects() ++;
00409
00410
00411 do {
00412 nextDestinationId_++;
00413 } while (nextDestinationId_ == 0 || nextDestinationId_ == UINT_MAX);
00414 unsigned int destinationId = nextDestinationId_;
00415
00416
00417 NetServerTCP2Destination *destination =
00418 new NetServerTCP2Destination(
00419 &incomingMessageHandler_, socket, destinationId);
00420 destinations_[destinationId] = destination;
00421
00422
00423 NetMessage *message = NetMessagePool::instance()->
00424 getFromPool(NetMessage::ConnectMessage,
00425 destinationId, destination->getIpAddress());
00426 incomingMessageHandler_.addMessage(message);
00427
00428
00429 return destinationId;
00430 }