Danbias/Code/Network/NetworkAPI/NetworkServer.cpp

293 lines
6.1 KiB
C++
Raw Normal View History

#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"
#include "../NetworkDependencies/WinsockFunctions.h"
2013-12-10 08:32:08 +01:00
2014-01-29 10:18:01 +01:00
#include "Utilities.h"
#include "Thread/OysterThread.h"
#ifndef _DEBUG
#include <winsock2.h>
#endif
2013-12-08 23:56:17 +01:00
using namespace Oyster::Network;
using namespace Utility::DynamicMemory;
using namespace Oyster::Thread;
2013-12-08 23:56:17 +01:00
/*************************************
PrivateData
*************************************/
2014-01-29 10:18:01 +01:00
void Broadcast()
{
char pkt[4];
size_t pkt_length = 4;
sockaddr_in dest;
sockaddr_in local;
WSAData data;
WSAStartup( MAKEWORD( 2, 2 ), &data );
local.sin_family = AF_INET;
local.sin_addr.s_addr = inet_addr( "127.0.0.1" );
local.sin_port = 15151; // choose any
dest.sin_family = AF_INET;
dest.sin_port = htons( 15151 );
// create the socket
SOCKET s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
// bind to the local address
bind( s, (sockaddr *)&local, sizeof(local) );
std::string addr;
for (int i = 0; i < 256; i++)
{
addr = "192.168.0.";
char buff[5];
_itoa_s<5>(i, buff, 10);
addr.append(buff);
dest.sin_addr.s_addr = inet_addr( addr.c_str() );
// send the pkt
int ret = sendto( s, pkt, pkt_length, 0, (sockaddr *)&dest, sizeof(dest) );
}
}
2013-12-10 08:32:08 +01:00
struct NetworkServer::PrivateData : public IThreadObject
{
2014-01-28 09:00:02 +01:00
public:
PrivateData()
: listener(0)
, mainSession(0)
, isInitiated(0)
, isReleased(0)
, isRunning(0)
2014-01-29 10:18:01 +01:00
, port(-1)
2014-01-28 09:00:02 +01:00
{ }
~PrivateData()
{ }
bool DoWork();
2014-01-28 09:00:02 +01:00
public:
2014-01-29 10:18:01 +01:00
Listener* listener;
PostBox<ConnectionInfo> postBox; //Postbox for new clients
2014-01-28 09:00:02 +01:00
OysterThread thread; //Server thread
NetworkSession *mainSession;
2014-01-29 10:18:01 +01:00
Utility::Container::ThreadSafeQueue<SmartPointer<NetworkClient>> clientQueue;
2014-01-28 09:00:02 +01:00
bool isInitiated;
bool isReleased;
bool isRunning;
int port;
};
2013-12-08 23:56:17 +01:00
2014-01-28 09:00:02 +01:00
bool NetworkServer::PrivateData::DoWork()
{
2014-01-29 10:18:01 +01:00
//Broadcast();
2014-01-28 09:00:02 +01:00
/** Check for new clients **/
if(postBox.IsFull())
{
ConnectionInfo clientSocketNum = postBox.FetchMessage();
if(clientSocketNum.socket == -1)
2014-01-28 09:00:02 +01:00
{
//Something went wrong somewhere... do we care?
}
2014-01-29 10:18:01 +01:00
SmartPointer<NetworkClient> client(new NetworkClient());
client->Connect(clientSocketNum);
this->clientQueue.Push(client);
2014-01-28 09:00:02 +01:00
}
2013-12-08 23:56:17 +01:00
2014-01-28 09:00:02 +01:00
return true;
2013-12-08 23:56:17 +01:00
}
2014-01-28 09:00:02 +01:00
/*************************************
NetworkServer
*************************************/
NetworkServer::NetworkServer()
{
this->privateData = new PrivateData();
}
NetworkServer::NetworkServer(const NetworkServer& obj)
{
delete this->privateData;
this->privateData = new PrivateData(*obj.privateData);
}
const NetworkServer& NetworkServer::operator=(const NetworkServer& obj)
2013-12-08 23:56:17 +01:00
{
2014-01-28 09:00:02 +01:00
delete this->privateData;
this->privateData = new PrivateData(*obj.privateData);
return *this;
}
NetworkServer::~NetworkServer()
{
if(this->privateData)
{
delete this->privateData;
this->privateData = 0;
}
}
2014-01-28 09:00:02 +01:00
NetworkServer::ServerReturnCode NetworkServer::Init(const int& port, NetworkSession const* mainSession)
2013-12-08 23:56:17 +01:00
{
2014-01-29 10:18:01 +01:00
this->privateData->mainSession = const_cast<NetworkSession*>(mainSession);
2013-12-08 23:56:17 +01:00
//Check if it's a valid port
2014-01-28 09:00:02 +01:00
if(port == 0 || port == -1)
2013-12-08 23:56:17 +01:00
{
2014-01-28 09:00:02 +01:00
return NetworkServer::ServerReturnCode_Error;
}
else if(this->privateData->port != 0 && this->privateData->port != -1)
{
return NetworkServer::ServerReturnCode_Error;
2013-12-08 23:56:17 +01:00
}
if(!InitWinSock())
2014-01-28 09:00:02 +01:00
{
return NetworkServer::ServerReturnCode_Error;
}
2013-12-08 23:56:17 +01:00
//Initiate listener
2014-01-28 09:00:02 +01:00
this->privateData->listener = new Listener(&this->privateData->postBox);
2014-01-29 10:18:01 +01:00
if(!this->privateData->listener->Init(port, false))
{
2014-01-28 09:00:02 +01:00
return NetworkServer::ServerReturnCode_Error;
}
2013-12-08 23:56:17 +01:00
2014-01-28 09:00:02 +01:00
if(this->privateData->thread.Create(this->privateData, false) == OYSTER_THREAD_ERROR_FAILED)
{
2014-01-28 09:00:02 +01:00
return NetworkServer::ServerReturnCode_Error;
}
2014-01-28 09:00:02 +01:00
this->privateData->isInitiated = true;
this->privateData->isReleased = false;
return NetworkServer::ServerReturnCode_Sucess;
2013-12-08 23:56:17 +01:00
}
2014-01-28 09:00:02 +01:00
NetworkServer::ServerReturnCode NetworkServer::Start()
{
2013-12-08 23:56:17 +01:00
//Start listener
2014-01-29 10:18:01 +01:00
if(!this->privateData->listener->Start())
{
2014-01-28 09:00:02 +01:00
return NetworkServer::ServerReturnCode_Error;
}
2014-01-28 09:00:02 +01:00
if(this->privateData->thread.Start() == OYSTER_THREAD_ERROR_FAILED)
{
2014-01-28 09:00:02 +01:00
return NetworkServer::ServerReturnCode_Error;
}
2014-01-28 09:00:02 +01:00
this->privateData->isRunning = true;
return NetworkServer::ServerReturnCode_Sucess;
2013-12-08 23:56:17 +01:00
}
2014-01-28 09:00:02 +01:00
void NetworkServer::Stop()
2013-12-08 23:56:17 +01:00
{
2014-01-28 09:00:02 +01:00
if(this->privateData->listener)
2013-12-08 23:56:17 +01:00
{
2014-01-29 10:18:01 +01:00
this->privateData->listener->Stop();
2013-12-08 23:56:17 +01:00
}
2014-01-28 09:00:02 +01:00
this->privateData->thread.Stop();
2013-12-08 23:56:17 +01:00
2014-01-28 09:00:02 +01:00
this->privateData->isRunning = false;
2013-12-08 23:56:17 +01:00
}
2014-01-28 09:00:02 +01:00
void NetworkServer::Shutdown()
2013-12-08 23:56:17 +01:00
{
2014-01-29 10:18:01 +01:00
if(this->privateData->mainSession)
{
this->privateData->mainSession->CloseSession(true);
}
2014-01-28 09:00:02 +01:00
if(this->privateData->listener)
2013-12-08 23:56:17 +01:00
{
2014-01-28 09:00:02 +01:00
this->privateData->listener->Shutdown();
delete this->privateData->listener;
this->privateData->listener = NULL;
2013-12-08 23:56:17 +01:00
}
2014-01-28 09:00:02 +01:00
this->privateData->thread.Terminate();
2013-12-08 23:56:17 +01:00
ShutdownWinSock();
2014-01-28 09:00:02 +01:00
this->privateData->isRunning = false;
this->privateData->mainSession = 0;
this->privateData->isReleased = true;
2013-12-08 23:56:17 +01:00
}
2014-01-30 00:19:00 +01:00
int NetworkServer::Update()
{
2014-01-29 10:18:01 +01:00
int c = 0;
2014-01-28 09:00:02 +01:00
while(!this->privateData->clientQueue.IsEmpty())
{
2014-01-29 10:18:01 +01:00
if(this->privateData->mainSession)
{
this->privateData->mainSession->ClientConnectedEvent(this->privateData->clientQueue.Pop());
c++;
}
else
{
//Clients have nowhere to go?
this->privateData->clientQueue.Pop()->Disconnect();
}
}
2014-01-29 10:18:01 +01:00
return c;
}
2014-01-28 09:00:02 +01:00
void NetworkServer::SetSession(NetworkSession const* mainSession)
{
2014-01-28 09:00:02 +01:00
this->privateData->mainSession = const_cast<NetworkSession*>(mainSession);
}
2014-01-28 09:00:02 +01:00
NetworkSession const* NetworkServer::GetMainSession()
2013-12-08 23:56:17 +01:00
{
2014-01-28 09:00:02 +01:00
return this->privateData->mainSession;
2013-12-08 23:56:17 +01:00
}
2014-01-29 10:18:01 +01:00
NetworkSession const* NetworkServer::ReleaseMainSession()
2013-12-08 23:56:17 +01:00
{
2014-01-28 09:00:02 +01:00
NetworkSession const * temp;
temp = this->privateData->mainSession;
this->privateData->mainSession = 0;
return temp;
}
bool NetworkServer::IsRunning() const
{
2014-01-28 09:00:02 +01:00
return this->privateData->isRunning;
}
2014-01-29 10:18:01 +01:00
std::string NetworkServer::GetLanAddress()
{
std::string szLocalIP;
char szHostName[255];
struct hostent *host_entry;
2014-01-29 10:18:01 +01:00
gethostname(szHostName, 255);
host_entry = gethostbyname(szHostName);
char* temp = inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
char buff[255];
strcpy_s(buff, temp);
szLocalIP = buff;
return szLocalIP;
}
2014-01-30 00:19:00 +01:00
int NetworkServer::GetPort()
{
2014-01-30 00:19:00 +01:00
return this->privateData->port;
}
2014-01-28 09:00:02 +01:00