2013-12-11 21:45:43 +01:00
|
|
|
#ifndef INCLUDE_WINSOCK_LIB
|
|
|
|
#define INCLUDE_WINSOCK_LIB
|
|
|
|
#pragma comment(lib, "ws2_32.lib")
|
|
|
|
#endif
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
#include "NetworkServer.h"
|
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
#include "../NetworkDependencies/Listener.h"
|
|
|
|
#include "../NetworkDependencies/PostBox.h"
|
2013-12-11 21:45:43 +01:00
|
|
|
#include "../NetworkDependencies/WinsockFunctions.h"
|
2013-12-10 08:32:08 +01:00
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
#include "../../Misc/Utilities.h"
|
2013-12-09 22:22:05 +01:00
|
|
|
#include "../../Misc/Thread/OysterThread.h"
|
2013-12-06 10:45:53 +01:00
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
using namespace Oyster::Network;
|
|
|
|
using namespace ::Server;
|
|
|
|
using namespace Utility::DynamicMemory;
|
2013-12-09 22:22:05 +01:00
|
|
|
using namespace Oyster::Thread;
|
2013-12-08 23:56:17 +01:00
|
|
|
|
|
|
|
/*************************************
|
|
|
|
PrivateData
|
|
|
|
*************************************/
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
struct NetworkServer::PrivateData : public IThreadObject
|
2013-12-06 10:45:53 +01:00
|
|
|
{
|
2013-12-08 23:56:17 +01:00
|
|
|
PrivateData();
|
|
|
|
~PrivateData();
|
|
|
|
|
|
|
|
bool Init(INIT_DESC& initDesc);
|
|
|
|
bool Start();
|
2013-12-11 21:45:43 +01:00
|
|
|
void Stop();
|
|
|
|
void Shutdown();
|
2013-12-09 22:22:05 +01:00
|
|
|
|
|
|
|
void CheckForNewClient();
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
bool DoWork();
|
2013-12-09 22:22:05 +01:00
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
//
|
|
|
|
IListener* listener;
|
|
|
|
INIT_DESC initDesc;
|
|
|
|
bool started;
|
|
|
|
|
2013-12-09 22:22:05 +01:00
|
|
|
//Postbox for new clients
|
|
|
|
IPostBox<int> *postBox;
|
|
|
|
|
|
|
|
//Server thread
|
|
|
|
OysterThread thread;
|
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
};
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
NetworkServer::PrivateData::PrivateData()
|
2013-12-08 23:56:17 +01:00
|
|
|
{
|
|
|
|
listener = 0;
|
|
|
|
started = false;
|
2013-12-09 22:22:05 +01:00
|
|
|
postBox = new PostBox<int>;
|
2013-12-08 23:56:17 +01:00
|
|
|
}
|
2013-12-06 10:45:53 +01:00
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
NetworkServer::PrivateData::~PrivateData()
|
2013-12-08 23:56:17 +01:00
|
|
|
{
|
|
|
|
Shutdown();
|
2013-12-06 10:45:53 +01:00
|
|
|
}
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
bool NetworkServer::PrivateData::Init(INIT_DESC& initDesc)
|
2013-12-08 23:56:17 +01:00
|
|
|
{
|
|
|
|
//Check if it's a valid port
|
|
|
|
if(initDesc.port == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
if(!InitWinSock())
|
|
|
|
return false;
|
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
this->initDesc = initDesc;
|
|
|
|
|
|
|
|
//Initiate listener
|
2013-12-09 22:22:05 +01:00
|
|
|
listener = new Listener(postBox);
|
2013-12-11 21:45:43 +01:00
|
|
|
if(!((Listener*)listener)->Init(this->initDesc.port, false))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-12-08 23:56:17 +01:00
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
if(thread.Create(this, false) == OYSTER_THREAD_ERROR_FAILED)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-12-09 22:22:05 +01:00
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
bool NetworkServer::PrivateData::Start()
|
2013-12-06 10:45:53 +01:00
|
|
|
{
|
2013-12-08 23:56:17 +01:00
|
|
|
//Start listener
|
2013-12-11 21:45:43 +01:00
|
|
|
if(!((Listener*)listener)->Start())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
started = true;
|
2013-12-06 10:45:53 +01:00
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
if(thread.Start() == OYSTER_THREAD_ERROR_FAILED)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-12-09 22:22:05 +01:00
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
void NetworkServer::PrivateData::Stop()
|
2013-12-08 23:56:17 +01:00
|
|
|
{
|
|
|
|
if(listener)
|
|
|
|
{
|
|
|
|
((Listener*)listener)->Stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
started = false;
|
|
|
|
|
2013-12-09 22:22:05 +01:00
|
|
|
thread.Stop();
|
2013-12-08 23:56:17 +01:00
|
|
|
}
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
void NetworkServer::PrivateData::Shutdown()
|
2013-12-08 23:56:17 +01:00
|
|
|
{
|
2013-12-09 22:22:05 +01:00
|
|
|
//Stop server main thread
|
|
|
|
thread.Stop();
|
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
if(listener)
|
|
|
|
{
|
|
|
|
delete listener;
|
|
|
|
listener = NULL;
|
|
|
|
}
|
|
|
|
|
2013-12-09 22:22:05 +01:00
|
|
|
if(postBox)
|
|
|
|
{
|
|
|
|
delete postBox;
|
|
|
|
postBox = NULL;
|
|
|
|
}
|
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
started = false;
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
ShutdownWinSock();
|
2013-12-08 23:56:17 +01:00
|
|
|
}
|
|
|
|
|
2013-12-09 22:22:05 +01:00
|
|
|
//Checks for new clients and sends them to the proc function.
|
2013-12-10 08:32:08 +01:00
|
|
|
void NetworkServer::PrivateData::CheckForNewClient()
|
2013-12-09 22:22:05 +01:00
|
|
|
{
|
|
|
|
if(postBox->IsFull())
|
|
|
|
{
|
2013-12-11 21:45:43 +01:00
|
|
|
int clientSocketNum = postBox->FetchMessage();
|
2013-12-09 22:22:05 +01:00
|
|
|
|
|
|
|
//Safety check that is probably not needed.
|
|
|
|
if(clientSocketNum == -1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
//Create client and Proc function if the pointer is not NULL
|
2013-12-11 21:45:43 +01:00
|
|
|
if(initDesc.callbackType == NetworkClientCallbackType_Function)
|
|
|
|
{
|
2013-12-17 10:25:34 +01:00
|
|
|
Oyster::Network::NetworkClient *client = new Oyster::Network::NetworkClient(clientSocketNum);
|
2013-12-11 21:45:43 +01:00
|
|
|
initDesc.recvObj.clientConnectFnc(client);
|
|
|
|
}
|
|
|
|
else if(initDesc.callbackType == NetworkClientCallbackType_Object)
|
2013-12-10 08:32:08 +01:00
|
|
|
{
|
2013-12-17 10:25:34 +01:00
|
|
|
Oyster::Network::NetworkClient *client = new Oyster::Network::NetworkClient(clientSocketNum);
|
2013-12-11 21:45:43 +01:00
|
|
|
initDesc.recvObj.clientConnectObject->ClientConnectCallback(client);
|
2013-12-10 08:32:08 +01:00
|
|
|
}
|
2013-12-09 22:22:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
bool NetworkServer::PrivateData::DoWork()
|
2013-12-09 22:22:05 +01:00
|
|
|
{
|
|
|
|
CheckForNewClient();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-12-08 23:56:17 +01:00
|
|
|
/*************************************
|
2013-12-10 08:32:08 +01:00
|
|
|
NetworkServer
|
2013-12-08 23:56:17 +01:00
|
|
|
*************************************/
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
NetworkServer::NetworkServer()
|
2013-12-08 23:56:17 +01:00
|
|
|
{
|
|
|
|
privateData = new PrivateData();
|
|
|
|
}
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
NetworkServer::~NetworkServer()
|
2013-12-08 23:56:17 +01:00
|
|
|
{
|
|
|
|
if(privateData)
|
|
|
|
{
|
|
|
|
delete privateData;
|
|
|
|
}
|
2013-12-06 10:45:53 +01:00
|
|
|
}
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
bool NetworkServer::Init(INIT_DESC& initDesc)
|
2013-12-06 10:45:53 +01:00
|
|
|
{
|
2013-12-11 21:45:43 +01:00
|
|
|
if(!privateData->Init(initDesc))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-12-06 10:45:53 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
bool NetworkServer::Start()
|
2013-12-06 10:45:53 +01:00
|
|
|
{
|
2013-12-11 21:45:43 +01:00
|
|
|
if(!privateData->Start())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-12-06 10:45:53 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
void NetworkServer::Stop()
|
2013-12-06 10:45:53 +01:00
|
|
|
{
|
2013-12-08 23:56:17 +01:00
|
|
|
privateData->Stop();
|
2013-12-06 10:45:53 +01:00
|
|
|
}
|
|
|
|
|
2013-12-11 21:45:43 +01:00
|
|
|
void NetworkServer::Shutdown()
|
2013-12-06 10:45:53 +01:00
|
|
|
{
|
2013-12-08 23:56:17 +01:00
|
|
|
privateData->Shutdown();
|
2013-12-06 10:45:53 +01:00
|
|
|
}
|
|
|
|
|
2013-12-10 08:32:08 +01:00
|
|
|
bool NetworkServer::IsStarted() const
|
2013-12-08 23:56:17 +01:00
|
|
|
{
|
|
|
|
return privateData->started;
|
2013-12-06 10:45:53 +01:00
|
|
|
}
|