00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef WIN32
00022 #define WIN32_LEAN_AND_MEAN
00023 #include <windows.h>
00024 #include <winsock2.h>
00025 #else
00026 #include <errno.h>
00027 #endif
00028
00029 #include <net/NetServerTCP2.h>
00030 #include <net/NetMessagePool.h>
00031 #include <net/NetOptions.h>
00032 #include <common/Logger.h>
00033 #include <common/Clock.h>
00034 #include <set>
00035
00036 static int SDLNet_TCP_Recv_Wrapper(TCPsocket sock, void *data, int maxlen)
00037 {
00038 #ifdef WIN32
00039 WSASetLastError(0);
00040 #else
00041 errno = 0;
00042 #endif
00043
00044 int result = SDLNet_TCP_Recv(sock, data, maxlen);
00045 if (result <= 0)
00046 {
00047 #ifdef WIN32
00048 int wsacp = WSAGetLastError();
00049 if (wsacp != WSAECONNRESET)
00050 {
00051 Logger::log(S3D::formatStringBuffer(
00052 "SDLNet_TCP_Recv_Wrapper: WSA Error code %i", wsacp));
00053 }
00054 #else
00055 int errnocp = errno;
00056 if (errnocp != ECONNRESET)
00057 {
00058 Logger::log(S3D::formatStringBuffer(
00059 "SDLNet_TCP_Recv_Wrapper: Error code %i", errnocp));
00060 }
00061 #endif
00062 }
00063
00064 return result;
00065 }
00066
00067 static int SDLNet_TCP_Send_Wrapper(TCPsocket sock, void *datap, int len)
00068 {
00069 #ifdef WIN32
00070 WSASetLastError(0);
00071 #else
00072 errno = 0;
00073 #endif
00074
00075 int result = SDLNet_TCP_Send(sock, datap, len);
00076 if (result <= 0)
00077 {
00078 #ifdef WIN32
00079 int wsacp = WSAGetLastError();
00080 if (wsacp != WSAECONNRESET)
00081 {
00082 Logger::log(S3D::formatStringBuffer(
00083 "SDLNet_TCP_Send_Wrapper: WSA Error code %i", wsacp));
00084 }
00085 #else
00086 int errnocp = errno;
00087 if (errnocp != ECONNRESET)
00088 {
00089 Logger::log(S3D::formatStringBuffer(
00090 "SDLNet_TCP_Send_Wrapper: Error code %i", errnocp));
00091 }
00092 #endif
00093 }
00094
00095 return result;
00096 }
00097
00098 NetServerTCP2Destination::NetServerTCP2Destination(
00099 NetMessageHandler *incomingMessageHandler,
00100 TCPsocket socket,
00101 unsigned int destinationId) :
00102 socket_(socket), socketSet_(0),
00103 currentMessage_(0), currentMessageLen_(0),
00104 currentMessageSentLen_(0),
00105 destinationId_(destinationId),
00106 packetLogging_(false),
00107 messagesSent_(0), messagesRecieved_(0),
00108 bytesIn_(0), bytesOut_(0),
00109 incomingMessageHandler_(incomingMessageHandler),
00110 sendRecvThread_(0),
00111 stopped_(false), finished_(false)
00112 {
00113 socketSet_ = SDLNet_AllocSocketSet(1);
00114 SDLNet_TCP_AddSocket(socketSet_, socket_);
00115
00116 outgoingMessageHandler_.setMessageHandler(this);
00117 packetLogging_ = NetOptions::instance()->getPacketLogging();
00118
00119 sendRecvThread_ = SDL_CreateThread(
00120 NetServerTCP2Destination::sendRecvThreadFunc, (void *) this);
00121 if (sendRecvThread_ == 0)
00122 {
00123 Logger::log(
00124 "NetServerTCP2Destination: Failed to create NetServerTCP2Destination thread");
00125 }
00126 }
00127
00128 NetServerTCP2Destination::~NetServerTCP2Destination()
00129 {
00130 SDLNet_FreeSocketSet(socketSet_);
00131 socketSet_ = 0;
00132
00133 if (socket_) SDLNet_TCP_Close(socket_);
00134 socket_ = 0;
00135
00136 if (currentMessage_) NetMessagePool::instance()->addToPool(currentMessage_);
00137 currentMessage_ = 0;
00138
00139 std::list<NetMessage *>::iterator itor;
00140 for (itor = outgoingMessages_.begin();
00141 itor != outgoingMessages_.end();
00142 itor++)
00143 {
00144 NetMessagePool::instance()->addToPool(*itor);
00145 }
00146
00147 int status;
00148 SDL_WaitThread(sendRecvThread_, &status);
00149 sendRecvThread_ = 0;
00150
00151 if (packetLogging_)
00152 {
00153 Logger::log(S3D::formatStringBuffer("NetServerTCP2Destination %u: destroyed",
00154 destinationId_));
00155 }
00156 }
00157
00158 unsigned int NetServerTCP2Destination::getIpAddress()
00159 {
00160 return getIpAddressFromSocket(socket_);
00161 }
00162
00163 unsigned int NetServerTCP2Destination::getIpAddressFromSocket(TCPsocket socket)
00164 {
00165 unsigned int addr = 0;
00166 IPaddress *address = SDLNet_TCP_GetPeerAddress(socket);
00167 if (address)
00168 {
00169 addr = SDLNet_Read32(&address->host);
00170 }
00171 return addr;
00172 }
00173
00174 int NetServerTCP2Destination::sendRecvThreadFunc(void *c)
00175 {
00176
00177 NetServerTCP2Destination *th = (NetServerTCP2Destination*) c;
00178 th->actualSendRecvFunc();
00179 th->finished_ = true;
00180 return 0;
00181 }
00182
00183 void NetServerTCP2Destination::actualSendRecvFunc()
00184 {
00185 Clock netClock;
00186 while (!stopped_)
00187 {
00188 {
00189
00190 netClock.getTimeDifference();
00191 }
00192
00193 {
00194
00195 outgoingMessageHandler_.processMessages();
00196 float timeDiff = netClock.getTimeDifference();
00197 if (timeDiff > 5.0f)
00198 {
00199 Logger::log(S3D::formatStringBuffer(
00200 "NetServerTCP2Destination %u: messages took %.2f seconds",
00201 destinationId_,
00202 timeDiff));
00203 }
00204 }
00205
00206 SocketResult sendResult;
00207 {
00208
00209 sendResult = checkOutgoing();
00210 float timeDiff = netClock.getTimeDifference();
00211 if (timeDiff > 5.0f)
00212 {
00213 Logger::log(S3D::formatStringBuffer(
00214 "NetServerTCP2Destination %u: outgoing took %.2f seconds",
00215 destinationId_,
00216 timeDiff));
00217 }
00218 if (sendResult == SocketClosed) break;
00219 }
00220
00221 SocketResult recvResult;
00222 {
00223
00224 recvResult = checkIncoming();
00225 float timeDiff = netClock.getTimeDifference();
00226 if (timeDiff > 5.0f)
00227 {
00228 Logger::log(S3D::formatStringBuffer(
00229 "NetServerTCP2Destination %u: incoming took %.2f seconds",
00230 destinationId_,
00231 timeDiff));
00232 }
00233 if (recvResult == SocketClosed) break;
00234 }
00235
00236 if (sendResult == SocketEmpty &&
00237 recvResult == SocketEmpty)
00238 {
00239 SDL_Delay(10);
00240 }
00241 }
00242
00243 if (packetLogging_)
00244 {
00245 Logger::log(S3D::formatStringBuffer("NetServerTCP2Destination %u: shutdown",
00246 destinationId_));
00247 }
00248 }
00249
00250 void NetServerTCP2Destination::processMessage(NetMessage &oldmessage)
00251 {
00252
00253 NetMessage *message = NetMessagePool::instance()->
00254 getFromPool(NetMessage::SentMessage,
00255 oldmessage.getDestinationId(), getIpAddress());
00256
00257
00258 NetBuffer &buffer = oldmessage.getBuffer();
00259 message->getBuffer().allocate(buffer.getBufferUsed());
00260 memcpy(message->getBuffer().getBuffer(),
00261 buffer.getBuffer(), buffer.getBufferUsed());
00262 message->getBuffer().setBufferUsed(buffer.getBufferUsed());
00263
00264
00265 outgoingMessages_.push_back(message);
00266
00267 if (packetLogging_)
00268 {
00269 Logger::log(S3D::formatStringBuffer(
00270 "NetServerTCP2Destination %u: Adding a new message, %u now waiting",
00271 destinationId_,
00272 outgoingMessages_.size()));
00273 }
00274 }
00275
00276 NetServerTCP2Destination::SocketResult NetServerTCP2Destination::checkIncoming()
00277 {
00278 bool activity = false;
00279 for (int i=0; i<2000; i++)
00280 {
00281
00282 int numready = SDLNet_CheckSockets(socketSet_, 0);
00283 if (numready == -1)
00284 {
00285
00286 {
00287 Logger::log(S3D::formatStringBuffer(
00288 "NetServerTCP2Destination %u: CheckSockets returned an error %i",
00289 destinationId_,
00290 numready));
00291 }
00292 return SocketClosed;
00293 }
00294 if (numready == 0) return (i==0?SocketEmpty:SocketActivity);
00295 if (!SDLNet_SocketReady(socket_)) return (activity?SocketActivity:SocketEmpty);
00296
00297
00298 char buffer[1];
00299 int recv = SDLNet_TCP_Recv_Wrapper(socket_, &buffer, 1);
00300 if (recv <= 0)
00301 {
00302
00303 {
00304 Logger::log(S3D::formatStringBuffer(
00305 "NetServerTCP2Destination %u: Recv returned an error %i",
00306 destinationId_,
00307 recv));
00308 }
00309 return SocketClosed;
00310 }
00311 currentMessagePart_.addDataToBuffer(buffer, 1);
00312
00313
00314 NetInterface::getBytesIn()++;
00315 bytesIn_++;
00316 activity = true;
00317
00318
00319 if (currentMessagePart_.getBufferUsed() == 5)
00320 {
00321 NetBufferReader reader(currentMessagePart_);
00322 reader.getFromBuffer(currentMessageType_);
00323 reader.getFromBuffer(currentMessageLen_);
00324 }
00325
00326
00327 if (currentMessagePart_.getBufferUsed() >= 5 &&
00328 currentMessagePart_.getBufferUsed() == currentMessageLen_)
00329 {
00330 if (currentMessageType_ & TypeMessage)
00331 {
00332 if (!currentMessage_)
00333 {
00334 currentMessage_ = NetMessagePool::instance()->
00335 getFromPool(NetMessage::BufferMessage,
00336 destinationId_, getIpAddress());
00337 }
00338
00339
00340 currentMessage_->getBuffer().addDataToBuffer(
00341 currentMessagePart_.getBuffer() + 5,
00342 currentMessagePart_.getBufferUsed() - 5);
00343 if (currentMessageType_ & TypeLast)
00344 {
00345
00346 messagesRecieved_++;
00347 incomingMessageHandler_->addMessage(currentMessage_);
00348 currentMessage_ = 0;
00349 }
00350
00351
00352 if (packetLogging_)
00353 {
00354 Logger::log(S3D::formatStringBuffer(
00355 "NetServerTCP2Destination %u: Recieved a message part, %s",
00356 destinationId_,
00357 (currentMessageType_ & TypeLast?"last":"not last")));
00358 }
00359 }
00360 else
00361 {
00362 Logger::log(S3D::formatStringBuffer(
00363 "NetServerTCP2Destination %u: Unknown message type %i received",
00364 destinationId_,
00365 currentMessageType_));
00366 return SocketClosed;
00367 }
00368
00369 currentMessageLen_ = 0;
00370 currentMessagePart_.reset();
00371 }
00372 }
00373
00374 return (activity?SocketActivity:SocketEmpty);
00375 }
00376
00377 NetServerTCP2Destination::SocketResult NetServerTCP2Destination::checkOutgoing()
00378 {
00379
00380 if (outgoingMessages_.empty()) return SocketEmpty;
00381
00382
00383 NetMessage *message = outgoingMessages_.front();
00384 int sendAmount = message->getBuffer().getBufferUsed() - currentMessageSentLen_;
00385 if (sendAmount > 100) sendAmount = 100;
00386
00387 if (currentMessageSentLen_ == 0)
00388 {
00389
00390 if(!sendHeader(TypeMessage | TypeLast,
00391 5 + message->getBuffer().getBufferUsed()))
00392 {
00393 return SocketClosed;
00394 }
00395 }
00396
00397
00398 int result = SDLNet_TCP_Send_Wrapper(socket_,
00399 (void *) &message->getBuffer().getBuffer()[currentMessageSentLen_],
00400 sendAmount);
00401 if(result < sendAmount)
00402 {
00403 Logger::log(S3D::formatStringBuffer(
00404 "NetServerTCP2Destination %u: Failed to send buffer %i of %i. Socket closed",
00405 destinationId_, result, sendAmount));
00406 return SocketClosed;
00407 }
00408
00409 NetInterface::getBytesOut() += result;
00410 bytesOut_ += result;
00411
00412
00413 currentMessageSentLen_ += sendAmount;
00414 if (currentMessageSentLen_ == message->getBuffer().getBufferUsed())
00415 {
00416 outgoingMessages_.pop_front();
00417 currentMessageSentLen_ = 0;
00418 incomingMessageHandler_->addMessage(message);
00419
00420 messagesSent_++;
00421 if (packetLogging_)
00422 {
00423 Logger::log(S3D::formatStringBuffer(
00424 "NetServerTCP2Destination %u: Sent a message part, %s",
00425 destinationId_,
00426 "last"));
00427 }
00428 }
00429
00430 return SocketActivity;
00431 }
00432
00433 bool NetServerTCP2Destination::sendHeader(char headerType, int len)
00434 {
00435 NetMessage *ackMessage = NetMessagePool::instance()->
00436 getFromPool(NetMessage::BufferMessage, 0, 0);
00437
00438
00439 ackMessage->getBuffer().addToBuffer(headerType);
00440 ackMessage->getBuffer().addToBuffer(len);
00441
00442
00443 int result = SDLNet_TCP_Send_Wrapper(socket_,
00444 (void *) ackMessage->getBuffer().getBuffer(),
00445 ackMessage->getBuffer().getBufferUsed());
00446
00447 NetInterface::getBytesOut() += result;
00448 bytesOut_ += result;
00449
00450 NetMessagePool::instance()->addToPool(ackMessage);
00451
00452 if (result != ackMessage->getBuffer().getBufferUsed())
00453 {
00454 Logger::log(S3D::formatStringBuffer(
00455 "NetServerTCP2Destination %u: Failed to send header %i of %i. Socket closed",
00456 destinationId_, result, ackMessage->getBuffer().getBufferUsed()));
00457 }
00458
00459 return (result == ackMessage->getBuffer().getBufferUsed());
00460 }
00461
00462 void NetServerTCP2Destination::printStats(unsigned int destination)
00463 {
00464 Logger::log(S3D::formatStringBuffer("TCP2 Destination %u net stats:", destination));
00465 Logger::log(S3D::formatStringBuffer(" %u messages sent, %u messages recieved",
00466 messagesSent_, messagesRecieved_));
00467 Logger::log(S3D::formatStringBuffer(" %u bytes in, %u bytes out",
00468 bytesIn_, bytesOut_));
00469 }