Network - NetworkServer, NetworkClient, Translator

First version of the NetworkAPI. It should work.
This commit is contained in:
Pontus Fransson 2013-12-11 21:45:43 +01:00
parent e06ee31754
commit 5a3188d5f6
33 changed files with 871 additions and 392 deletions

View File

@ -3,8 +3,8 @@
/////////////////////////////////////////////////////////////////////
#include "CustomNetProtocol.h"
#include <map>
using namespace Network;
#include "Translator.h"
using namespace Oyster::Network;
struct CustomNetProtocol::PrivateData

View File

@ -12,10 +12,14 @@
#define NET_PROTOCOL_EXPORT __declspec(dllimport)
#endif
namespace Network
namespace Oyster
{
namespace Network
{
extern "C"
{
//Please don't create a type with a number higher than 127 for now.
//This may increase to 255 later on.
enum NetAttributeType
{
NetAttributeType_Bool,
@ -84,10 +88,13 @@ namespace Network
private:
struct PrivateData;
PrivateData* privateData;
friend class Translator;
};
}//End extern "C"
} //End namespace Network
} //End namespace Network
}
#endif // !NETWORK_CUSTOM_NETWORK_PROTOCOL_H

View File

@ -163,11 +163,14 @@
<ClCompile Include="CustomNetProtocol.cpp" />
<ClCompile Include="NetworkServer.cpp" />
<ClCompile Include="NetworkClient.cpp" />
<ClCompile Include="Translator.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CustomNetProtocol.h" />
<ClInclude Include="NetworkCallbackHelper.h" />
<ClInclude Include="NetworkServer.h" />
<ClInclude Include="NetworkClient.h" />
<ClInclude Include="Translator.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NetworkDependencies\NetworkDependencies.vcxproj">

View File

@ -0,0 +1,48 @@
#ifndef NETWORK_API_NETWORK_CALLBACK_HELPER_H
#define NETWORK_API_NETWORK_CALLBACK_HELPER_H
/////////////////////////////////////
// Created by Dennis Andersen 2013 //
/////////////////////////////////////
namespace Oyster
{
namespace Network
{
enum NetworkProtocolCallbackType
{
NetworkProtocolCallbackType_Function,
NetworkProtocolCallbackType_Object,
NetworkProtocolCallbackType_Unknown = -1,
};
enum NetworkClientCallbackType
{
NetworkClientCallbackType_Function,
NetworkClientCallbackType_Object,
NetworkClientCallbackType_Unknown = -1,
};
class NetworkClient;
class CustomNetProtocol;
typedef void (*ClientConnectCallbackMethod)(NetworkClient&);
typedef void(*ProtocolRecieverFunction)(CustomNetProtocol& protocol);
struct ClientConnectedObject
{
virtual void ClientConnectCallback(NetworkClient &client) = 0;
};
struct ProtocolRecieverObject
{
virtual void ProtocolRecievedCallback(CustomNetProtocol& protocol) = 0;
};
union RecieverObject
{
ClientConnectCallbackMethod clientConnectFnc;
ProtocolRecieverFunction protocolRecieverFnc;
ClientConnectedObject *clientConnectObject;
ProtocolRecieverObject *protocolRecievedObject;
};
}
}
#endif

View File

@ -1,41 +1,243 @@
#ifndef INCLUDE_WINSOCK_LIB
#define INCLUDE_WINSOCK_LIB
#pragma comment(lib, "ws2_32.lib")
#endif
#include "NetworkClient.h"
#include "Translator.h"
#include "CustomNetProtocol.h"
#include "../NetworkDependencies/Connection.h"
#include "../NetworkDependencies/PostBox.h"
#include "../NetworkDependencies/WinsockFunctions.h"
#include "../../Misc/Utilities.h"
#include "../../Misc/Thread/IThreadObject.h"
#include "../../Misc/Thread/OysterThread.h"
using namespace Oyster::Network;
using namespace Oyster::Thread;
using namespace Utility::DynamicMemory;
/*************************************
PrivateData
*************************************/
struct PrivateData
struct NetworkClient::PrivateData : public IThreadObject
{
PrivateData();
PrivateData(unsigned int socket);
~PrivateData();
void Start();
void Send(CustomNetProtocol& protocol); //Is called from the outside to add messages to send.
//Called on from the thread
int Send();
int Recv();
bool DoWork();
Connection* connection;
IPostBox<CustomNetProtocol> *sendPostBox;
RecieverObject recvObj;
NetworkProtocolCallbackType callbackType;
Oyster::Thread::OysterThread thread;
std::mutex recvObjMutex;
std::mutex postBoxMutex;
Translator translator;
};
NetworkClient::PrivateData::PrivateData()
{
InitWinSock();
callbackType = NetworkProtocolCallbackType_Unknown;
connection = new Connection();
sendPostBox = new PostBox<CustomNetProtocol>;
this->thread.Create(this, false);
Start();
}
NetworkClient::PrivateData::PrivateData(unsigned int socket)
{
InitWinSock();
callbackType = NetworkProtocolCallbackType_Unknown;
connection = new Connection(socket);
sendPostBox = new PostBox<CustomNetProtocol>;
this->thread.Create(this, false);
Start();
}
NetworkClient::PrivateData::~PrivateData()
{
thread.Stop();
if(connection)
{
delete connection;
connection = NULL;
}
if(sendPostBox)
{
delete sendPostBox;
sendPostBox = NULL;
}
callbackType = NetworkProtocolCallbackType_Unknown;
ShutdownWinSock();
}
bool NetworkClient::PrivateData::DoWork()
{
Send();
Recv();
return true;
}
void NetworkClient::PrivateData::Send(CustomNetProtocol& protocol)
{
postBoxMutex.lock();
sendPostBox->PostMessage(protocol);
postBoxMutex.unlock();
}
int NetworkClient::PrivateData::Send()
{
int errorCode = 0;
postBoxMutex.lock();
if(sendPostBox->IsFull())
{
SmartPointer<OysterByte> temp = new OysterByte;
this->translator.Pack(temp, sendPostBox->FetchMessage());
errorCode = this->connection->Send(temp);
}
postBoxMutex.unlock();
return errorCode;
}
int NetworkClient::PrivateData::Recv()
{
int errorCode = -1;
SmartPointer<OysterByte> temp = new OysterByte;
errorCode = this->connection->Recieve(temp);
if(errorCode == 0)
{
CustomNetProtocol protocol;
bool ok = translator.Unpack(protocol, temp);
//Check if the protocol was unpacked correctly
if(ok)
{
recvObjMutex.lock();
if(callbackType == NetworkProtocolCallbackType_Function)
{
recvObj.protocolRecieverFnc(protocol);
}
else if(callbackType == NetworkProtocolCallbackType_Object)
{
recvObj.protocolRecievedObject->ProtocolRecievedCallback(protocol);
}
recvObjMutex.unlock();
}
}
return errorCode;
}
void NetworkClient::PrivateData::Start()
{
this->thread.Start();
}
/*************************************
NetworkClient
*************************************/
NetworkClient::NetworkClient()
{
privateData = new PrivateData();
}
NetworkClient::NetworkClient(unsigned int socket)
{
privateData = new PrivateData(socket);
}
NetworkClient::NetworkClient(RecieverObject recvObj, NetworkProtocolCallbackType type)
{
privateData = new PrivateData();
this->privateData->recvObj = recvObj;
}
NetworkClient::NetworkClient(RecieverObject recvObj, NetworkProtocolCallbackType type, unsigned int socket)
{
privateData = new PrivateData(socket);
this->privateData->recvObj = recvObj;
this->privateData->callbackType = type;
}
NetworkClient::~NetworkClient()
{
if(privateData)
{
delete privateData;
privateData = NULL;
}
}
bool NetworkClient::Connect(unsigned short port, const char serverIP[])
{
int result = this->privateData->connection->Connect(port, serverIP);
//Connect has succeeded
if(result == 0)
{
privateData->Start();
return true;
}
//Connect has failed
return false;
}
void NetworkClient::Disconnect()
{
privateData->connection->Disconnect();
}
bool NetworkClient::IsConnected()
{
return false;
return privateData->connection->IsConnected();
}
void NetworkClient::Send()
void NetworkClient::Send(CustomNetProtocol& protocol)
{
this->privateData->Send(protocol);
}
void NetworkClient::SetRecieverObject(RecieverObject recvObj, NetworkProtocolCallbackType type)
{
privateData->recvObjMutex.lock();
privateData->recvObj = recvObj;
privateData->callbackType = type;
privateData->recvObjMutex.unlock();
}

View File

@ -11,7 +11,7 @@
#define NET_PROTOCOL_EXPORT __declspec(dllimport)
#endif
class RecieverObject;
#include "NetworkCallbackHelper.h"
namespace Oyster
{
@ -23,12 +23,19 @@ namespace Oyster
{
public:
NetworkClient();
NetworkClient(unsigned int socket);
NetworkClient(RecieverObject recvObj, NetworkProtocolCallbackType type);
NetworkClient(RecieverObject recvObj, NetworkProtocolCallbackType type, unsigned int socket);
virtual ~NetworkClient();
virtual void Disconnect();
virtual bool IsConnected();
bool Connect(unsigned short port, const char serverIP[]);
void Disconnect();
virtual void Send();
bool IsConnected();
void Send(CustomNetProtocol& protocol);
void SetRecieverObject(RecieverObject recvObj, NetworkProtocolCallbackType type);
private:
struct PrivateData;

View File

@ -1,8 +1,13 @@
#ifndef INCLUDE_WINSOCK_LIB
#define INCLUDE_WINSOCK_LIB
#pragma comment(lib, "ws2_32.lib")
#endif
#include "NetworkServer.h"
#include "NetworkClient.h"
#include "../NetworkDependencies/Listener.h"
#include "../NetworkDependencies/PostBox.h"
#include "../NetworkDependencies/WinsockFunctions.h"
#include "../../Misc/Utilities.h"
#include "../../Misc/Thread/OysterThread.h"
@ -23,12 +28,12 @@ struct NetworkServer::PrivateData : public IThreadObject
bool Init(INIT_DESC& initDesc);
bool Start();
bool Stop();
bool Shutdown();
void Stop();
void Shutdown();
void CheckForNewClient();
virtual bool DoWork();
bool DoWork();
//
IListener* listener;
@ -63,13 +68,22 @@ bool NetworkServer::PrivateData::Init(INIT_DESC& initDesc)
return false;
}
if(!InitWinSock())
return false;
this->initDesc = initDesc;
//Initiate listener
listener = new Listener(postBox);
((Listener*)listener)->Init(this->initDesc.port, false);
if(!((Listener*)listener)->Init(this->initDesc.port, false))
{
return false;
}
thread.Create(this, false);
if(thread.Create(this, false) == OYSTER_THREAD_ERROR_FAILED)
{
return false;
}
return true;
}
@ -77,15 +91,22 @@ bool NetworkServer::PrivateData::Init(INIT_DESC& initDesc)
bool NetworkServer::PrivateData::Start()
{
//Start listener
((Listener*)listener)->Start();
if(!((Listener*)listener)->Start())
{
return false;
}
started = true;
thread.Start();
if(thread.Start() == OYSTER_THREAD_ERROR_FAILED)
{
return false;
}
return true;
}
bool NetworkServer::PrivateData::Stop()
void NetworkServer::PrivateData::Stop()
{
if(listener)
{
@ -95,11 +116,9 @@ bool NetworkServer::PrivateData::Stop()
started = false;
thread.Stop();
return true;
}
bool NetworkServer::PrivateData::Shutdown()
void NetworkServer::PrivateData::Shutdown()
{
//Stop server main thread
thread.Stop();
@ -118,7 +137,7 @@ bool NetworkServer::PrivateData::Shutdown()
started = false;
return true;
ShutdownWinSock();
}
//Checks for new clients and sends them to the proc function.
@ -126,8 +145,7 @@ void NetworkServer::PrivateData::CheckForNewClient()
{
if(postBox->IsFull())
{
int clientSocketNum;
postBox->FetchMessage(clientSocketNum);
int clientSocketNum = postBox->FetchMessage();
//Safety check that is probably not needed.
if(clientSocketNum == -1)
@ -136,10 +154,15 @@ void NetworkServer::PrivateData::CheckForNewClient()
}
//Create client and Proc function if the pointer is not NULL
if(initDesc.proc)
if(initDesc.callbackType == NetworkClientCallbackType_Function)
{
Oyster::Network::NetworkClient* client = new Oyster::Network::NetworkClient();
initDesc.proc((NetworkClient*)client);
Oyster::Network::NetworkClient client(clientSocketNum);
initDesc.recvObj.clientConnectFnc(client);
}
else if(initDesc.callbackType == NetworkClientCallbackType_Object)
{
Oyster::Network::NetworkClient client(clientSocketNum);
initDesc.recvObj.clientConnectObject->ClientConnectCallback(client);
}
}
}
@ -170,30 +193,32 @@ NetworkServer::~NetworkServer()
bool NetworkServer::Init(INIT_DESC& initDesc)
{
privateData->Init(initDesc);
if(!privateData->Init(initDesc))
{
return false;
}
return true;
}
bool NetworkServer::Start()
{
privateData->Start();
if(!privateData->Start())
{
return false;
}
return true;
}
bool NetworkServer::Stop()
void NetworkServer::Stop()
{
privateData->Stop();
return true;
}
bool NetworkServer::Shutdown()
void NetworkServer::Shutdown()
{
privateData->Shutdown();
return true;
}
bool NetworkServer::IsStarted() const

View File

@ -11,37 +11,35 @@
#define NET_PROTOCOL_EXPORT __declspec(dllimport)
#endif
#pragma comment(lib, "ws2_32.lib")
//#include "NetworkClient.h"
#include "NetworkClient.h"
#include "NetworkCallbackHelper.h"
namespace Oyster
{
namespace Network
{
namespace Server
{
extern "C"
{
class NET_PROTOCOL_EXPORT NetworkServer
{
public:
class NetworkClient;
struct INIT_DESC
{
unsigned short port; //Port the server should be accepting clients on.
void (*proc)(NetworkClient*);
NetworkClientCallbackType callbackType; //The recieverObject type. Function or object.
RecieverObject recvObj; //The functions that is called when a new client has connected.
};
NetworkServer();
virtual ~NetworkServer();
virtual bool Init(INIT_DESC& initDesc);
virtual bool Start();
virtual bool Stop();
virtual bool Shutdown();
bool Init(INIT_DESC& initDesc);
bool Start();
void Stop();
void Shutdown();
virtual bool IsStarted() const;
bool IsStarted() const;
private:
struct PrivateData;
@ -50,7 +48,6 @@ namespace Oyster
};
}
}
}
}
#endif

View File

@ -0,0 +1,241 @@
#include "Translator.h"
#include <string>
#include <map>
#include "CustomNetProtocol.h"
#include "../NetworkDependencies/Messages/MessageHeader.h"
#include "../NetworkDependencies/OysterByte.h"
using namespace Oyster::Network;
using namespace ::Messages;
using namespace Utility::DynamicMemory;
using namespace std;
struct MyCastingStruct
{
std::map<int, NetAttributeContainer> attributes;
/*MyCastingStruct()
{ }
~MyCastingStruct()
{
for (auto i = attributes.begin(); i != attributes.end(); i++)
{
RemoveAttribute(i->first);
}
}
void RemoveAttribute(int ID)
{
auto i = attributes.find(ID);
if(i == attributes.end()) return;
switch (i->second.type)
{
case NetAttributeType_CharArray:
delete [] i->second.value.netCharPtr;
break;
}
}*/
};
// TODO: Check if the package has been packed correctly.
struct Translator::PrivateData
{
PrivateData()
{
numberOfUnknownTypes = 0;
size = 0;
}
//Packages a header with a size(int) and a string of characters(char)
void PackHeader(SmartPointer<OysterByte> &bytes, CustomNetProtocol& protocol)
{
auto it = ((MyCastingStruct*)protocol.privateData)->attributes.begin();
auto end = ((MyCastingStruct*)protocol.privateData)->attributes.end();
size = 4 + 2; //size(int) + number of chars(short)
message.SetSize(size);
//Find all the data types
for(; it != end; it++)
{
headerString.push_back(it->second.type);
}
message.PackShort(size, *bytes);
for(int i = 0; i < (int)headerString.size(); i++)
{
message.PackChar(headerString.at(i), *bytes);
size++;
}
message.SetSize(bytes);
}
void PackMessage(SmartPointer<OysterByte> &bytes, CustomNetProtocol& protocol)
{
auto it = ((MyCastingStruct*)protocol.privateData)->attributes.begin();
auto end = ((MyCastingStruct*)protocol.privateData)->attributes.end();
for(int i = 0; i < (int)headerString.size(); i++)
{
switch((int)headerString.at(i))
{
case NetAttributeType_Bool:
message.PackBool(it->second.value.netBool, *bytes);
break;
case NetAttributeType_Char:
message.PackChar(it->second.value.netChar, *bytes);
break;
case NetAttributeType_UnsignedChar:
message.PackUnsignedChar(it->second.value.netUChar, *bytes);
break;
case NetAttributeType_Short:
message.PackShort(it->second.value.netShort, *bytes);
break;
case NetAttributeType_UnsignedShort:
message.PackUnsignedShort(it->second.value.netUShort, *bytes);
break;
case NetAttributeType_Int:
message.PackInt(it->second.value.netInt, *bytes);
break;
case NetAttributeType_UnsignedInt:
message.PackUnsignedInt(it->second.value.netUInt, *bytes);
break;
case NetAttributeType_Int64:
message.PackInt64(it->second.value.netInt64, *bytes);
break;
case NetAttributeType_UnsignedInt64:
message.PackUnsignedInt64(it->second.value.netUInt64, *bytes);
break;
case NetAttributeType_Float:
message.PackFloat(it->second.value.netFloat, *bytes);
break;
case NetAttributeType_Double:
message.PackDouble(it->second.value.netDouble, *bytes);
break;
case NetAttributeType_CharArray:
message.PackStr(it->second.value.netCharPtr, *bytes);
break;
default:
numberOfUnknownTypes++;
break;
}
}
message.SetSize(bytes);
}
bool UnpackHeader(CustomNetProtocol& protocol, SmartPointer<OysterByte> &bytes)
{
message.SetSize(0);
int packageSize = message.UnpackInt(*bytes);
if(packageSize != bytes->GetSize())
{
return false;
}
short numberOfTypes = message.UnpackShort(*bytes);
for(int i = 0; i < numberOfTypes; i++)
{
char temp = message.UnpackChar(*bytes);
headerString.push_back(temp);
}
return true;
}
void UnpackMessage(CustomNetProtocol& protocol, SmartPointer<OysterByte> &bytes)
{
for(int i = 0; i < (int)headerString.size(); i++)
{
protocol[i].type = (NetAttributeType)headerString.at(i);
switch(protocol[i].type)
{
case NetAttributeType_Bool:
protocol[i].value.netBool = message.UnpackBool(*bytes);
break;
case NetAttributeType_Char:
protocol[i].value.netChar = message.UnpackChar(*bytes);
break;
case NetAttributeType_UnsignedChar:
protocol[i].value.netUChar = message.UnpackUnsignedChar(*bytes);
break;
case NetAttributeType_Short:
protocol[i].value.netShort = message.UnpackShort(*bytes);
break;
case NetAttributeType_UnsignedShort:
protocol[i].value.netUShort = message.UnpackUnsignedShort(*bytes);
break;
case NetAttributeType_Int:
protocol[i].value.netInt = message.UnpackInt(*bytes);
break;
case NetAttributeType_UnsignedInt:
protocol[i].value.netUInt = message.UnpackUnsignedInt(*bytes);
break;
case NetAttributeType_Int64:
protocol[i].value.netInt64 = message.UnpackInt64(*bytes);
break;
case NetAttributeType_UnsignedInt64:
protocol[i].value.netUInt64 = message.UnpackUnsignedInt64(*bytes);
break;
case NetAttributeType_Float:
protocol[i].value.netFloat = message.UnpackFloat(*bytes);
break;
case NetAttributeType_Double:
protocol[i].value.netDouble = message.UnpackDouble(*bytes);
break;
case NetAttributeType_CharArray:
//protocol[i].value.netCharPtr = message.UnpackStr(*bytes).c_str();
break;
default:
numberOfUnknownTypes++;
break;
}
}
}
MessageHeader message;
string headerString;
unsigned int size;
int numberOfUnknownTypes;
};
Translator::Translator()
{
privateData = new PrivateData();
}
Translator::~Translator()
{
if(privateData)
{
delete privateData;
privateData = NULL;
}
}
void Translator::Pack(SmartPointer<OysterByte> &bytes, CustomNetProtocol& protocol)
{
privateData->headerString.clear();
privateData->PackHeader(bytes, protocol);
privateData->PackMessage(bytes, protocol);
}
bool Translator::Unpack(CustomNetProtocol& protocol, SmartPointer<OysterByte> &bytes)
{
if(!privateData->UnpackHeader(protocol, bytes))
{
return false;
}
privateData->UnpackMessage(protocol, bytes);
return true;
}

View File

@ -0,0 +1,65 @@
#ifndef NETWORK_DEPENDENCIES_TRANSLATOR_H
#define NETWORK_DEPENDENCIES_TRANSLATOR_H
//////////////////////////////////
// Created by Sam Svensson 2013 //
// ----------------------------//
// Packs our dynamic protocols //
//////////////////////////////////
/*
It packs a header in front of the actual message.
Header looks like this:
- Size of the entire package
- String containing all the types of data that is packed in the package.
*/
/*
Possible optimizing:
If there are several of the same type of data in a row,
we can instead of saving a character for each type we can instead save a number and the character.
Example:
If we are packing 100 floats.
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF..."
Instead of that we can do this:
"100F"
*/
#ifdef CUSTOM_NET_PROTOCOL_EXPORT
#define NET_PROTOCOL_EXPORT __declspec(dllexport)
#else
#define NET_PROTOCOL_EXPORT __declspec(dllimport)
#endif
#include "../../Misc/Utilities.h"
namespace Oyster
{
namespace Network
{
extern "C"
{
class OysterByte;
class CustomNetProtocol;
class NET_PROTOCOL_EXPORT Translator
{
public:
Translator ();
~Translator();
void Pack(Utility::DynamicMemory::SmartPointer<OysterByte> &bytes, CustomNetProtocol& protocol);
//Returns false if it discovers any faulty stuff with the package.
bool Unpack(CustomNetProtocol& protocol, Utility::DynamicMemory::SmartPointer<OysterByte> &bytes);
private:
struct PrivateData;
PrivateData* privateData;
};
}
}
}
#endif

View File

@ -94,9 +94,14 @@ int Connection::InitiateClient()
int Connection::Disconnect()
{
closesocket(this->socket);
int result = closesocket(this->socket);
if(result == SOCKET_ERROR)
{
return WSAGetLastError();
}
return 0;
}
int Connection::Send(Utility::DynamicMemory::SmartPointer<OysterByte> &bytes)
@ -117,9 +122,10 @@ int Connection::Recieve(Utility::DynamicMemory::SmartPointer<OysterByte> &bytes)
int nBytes;
bytes->Resize(1000);
nBytes = recv(this->socket, *bytes , 500, 0);
nBytes = recv(this->socket, *bytes, 1000, 0);
if(nBytes == SOCKET_ERROR)
{
bytes->SetSize(0);
return WSAGetLastError();
}
else
@ -127,11 +133,10 @@ int Connection::Recieve(Utility::DynamicMemory::SmartPointer<OysterByte> &bytes)
bytes->SetSize(nBytes);
}
std::cout << "Size of the recieved data: " << nBytes << " bytes" << std::endl;
return 0;
}
//Listen will only return the correct socket or -1 for failure.
int Connection::Listen()
{
int clientSocket;
@ -143,18 +148,14 @@ int Connection::Listen()
return clientSocket;
}
///////////////////////////////////////
//Private functions
///////////////////////////////////////
int Connection::InitiateSocket()
bool Connection::IsSending()
{
this->socket = (int)::socket(AF_INET, SOCK_STREAM, 0);
if(this->socket == SOCKET_ERROR)
{
return WSAGetLastError();
}
return stillSending;
}
return 0;
bool Connection::IsConnected()
{
return !closed;
}
int Connection::SetBlockingMode(bool blocking)
@ -178,3 +179,17 @@ int Connection::SetBlockingMode(bool blocking)
return 0;
}
///////////////////////////////////////
//Private functions
///////////////////////////////////////
int Connection::InitiateSocket()
{
this->socket = (int)::socket(AF_INET, SOCK_STREAM, 0);
if(this->socket == SOCKET_ERROR)
{
return WSAGetLastError();
}
return 0;
}

View File

@ -31,6 +31,9 @@ namespace Oyster
virtual int Listen();
bool IsSending();
bool IsConnected();
//Setting the socket to blocking/non-blocking mode.
int SetBlockingMode( bool blocking );

View File

@ -15,7 +15,7 @@ namespace Oyster
public:
virtual ~IPostBox() {}
virtual void PostMessage(T& message) = 0;
virtual bool FetchMessage(T& message) = 0;
virtual T FetchMessage() = 0;
virtual bool IsFull() = 0;
};

View File

@ -11,14 +11,14 @@ namespace Oyster
{
namespace Network
{
class CustomNetProtocol;
class OysterByte;
class ITranslate
{
public:
//packs and unpacks packages for sending or recieving over the connection
virtual void Pack (Protocols::ProtocolHeader &header, Utility::DynamicMemory::SmartPointer<OysterByte> &bytes) = 0;
virtual void Unpack (Protocols::ProtocolSet* set, Utility::DynamicMemory::SmartPointer<OysterByte> &bytes ) = 0;
virtual void Pack (Utility::DynamicMemory::SmartPointer<OysterByte> &bytes, Oyster::Network::CustomNetProtocol* protocol);
virtual void Unpack (Oyster::Network::CustomNetProtocol* protocol, Utility::DynamicMemory::SmartPointer<OysterByte> &bytes);
};
}

View File

@ -2,6 +2,7 @@
using namespace Oyster::Network::Server;
using namespace Utility::DynamicMemory;
using namespace Oyster::Thread;
Listener::Listener()
{
@ -28,7 +29,10 @@ bool Listener::Init(unsigned int port)
connection = new Connection();
connection->InitiateServer(port);
thread.Create(this, true);
if(thread.Create(this, true) == OYSTER_THREAD_ERROR_FAILED)
{
return false;
}
return true;
}
@ -36,16 +40,27 @@ bool Listener::Init(unsigned int port)
bool Listener::Init(unsigned int port, bool start)
{
connection = new Connection();
connection->InitiateServer(port);
if(connection->InitiateServer(port) != 0)
{
return false;
}
thread.Create(this, start);
if(thread.Create(this, start) == OYSTER_THREAD_ERROR_FAILED)
{
return false;
}
return true;
}
void Listener::Start()
bool Listener::Start()
{
thread.Start();
if(thread.Start() == OYSTER_THREAD_ERROR_FAILED)
{
return false;
}
return true;
}
void Listener::Stop()
@ -61,9 +76,7 @@ void Listener::Shutdown()
void Listener::SetPostBox(Oyster::Network::IPostBox<int>* postBox)
{
stdMutex.lock();
//mutex.LockMutex();
this->postBox = postBox;
//mutex.UnlockMutex();
stdMutex.unlock();
}
@ -75,9 +88,7 @@ int Listener::Accept()
if(clientSocket != -1)
{
stdMutex.lock();
//mutex.LockMutex();
postBox->PostMessage(clientSocket);
//mutex.UnlockMutex();
stdMutex.unlock();
}
@ -86,7 +97,12 @@ int Listener::Accept()
bool Listener::DoWork()
{
Accept();
int result = Accept();
if(result == -1)
{
//Do something?
}
return true;
}

View File

@ -27,7 +27,7 @@ namespace Oyster
bool Init(unsigned int port);
bool Init(unsigned int port, bool start);
void Start();
bool Start();
void Stop();
void Shutdown();

View File

@ -251,3 +251,8 @@ void MessageHeader::SetSize(OysterByte& bytes)
{
Packing::Pack(bytes, size);
}
void MessageHeader::SetSize(unsigned int size)
{
this->size = size;
}

View File

@ -24,7 +24,6 @@ namespace Oyster
virtual void Pack(Protocols::ProtocolHeader& header, OysterByte& bytes );
virtual void Unpack(OysterByte& bytes, Protocols::ProtocolHeader& header);
protected:
//Pack variables to messages
void PackBool(bool i, OysterByte& bytes);
@ -47,10 +46,6 @@ namespace Oyster
void PackStr(char str[], OysterByte& bytes);
void PackStr(std::string str, OysterByte& bytes);
//Maybe
//TODO: Add Pack functions for Vec2, 3, 4 and maybe Matrix. Etc.
//Unpack variables from message
bool UnpackBool(OysterByte& bytes);
@ -72,13 +67,11 @@ namespace Oyster
std::string UnpackStr(OysterByte& bytes);
//Maybe
//TODO: Add Unpack functions for Vec2, 3, 4 and maybe Matrix. Etc.
//Sets the this->size to the first position in msg
void SetSize(OysterByte& bytes);
void SetSize(unsigned int size);
private:
unsigned int size;

View File

@ -159,7 +159,6 @@
<ClCompile Include="OysterByte.cpp" />
<ClCompile Include="Packing.cpp" />
<ClCompile Include="ThreadedClient.cpp" />
<ClCompile Include="Translator.cpp" />
<ClCompile Include="WinsockFunctions.cpp" />
</ItemGroup>
<ItemGroup>
@ -178,7 +177,6 @@
<ClInclude Include="PostBox.h" />
<ClInclude Include="Protocols.h" />
<ClInclude Include="ThreadedClient.h" />
<ClInclude Include="Translator.h" />
<ClInclude Include="WinsockFunctions.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -9,7 +9,6 @@
<ClCompile Include="OysterByte.cpp" />
<ClCompile Include="Packing.cpp" />
<ClCompile Include="ThreadedClient.cpp" />
<ClCompile Include="Translator.cpp" />
<ClCompile Include="WinsockFunctions.cpp" />
</ItemGroup>
<ItemGroup>
@ -28,7 +27,6 @@
<ClInclude Include="PostBox.h" />
<ClInclude Include="Protocols.h" />
<ClInclude Include="ThreadedClient.h" />
<ClInclude Include="Translator.h" />
<ClInclude Include="WinsockFunctions.h" />
</ItemGroup>
</Project>

View File

@ -23,7 +23,7 @@ namespace Oyster
virtual ~PostBox();
virtual void PostMessage(T& message);
virtual bool FetchMessage(T& message);
virtual T FetchMessage();
virtual bool IsFull();
private:
@ -49,14 +49,9 @@ namespace Oyster
}
template <class T>
bool PostBox<T>::FetchMessage(T& message)
T PostBox<T>::FetchMessage()
{
if(IsFull())
{
message = messages.Pop();
return true;
}
return false;
return messages.Pop();
}
template <class T>

View File

@ -9,7 +9,7 @@ using namespace Utility::DynamicMemory;
ThreadedClient::ThreadedClient()
{
this->connection = new Connection();
this->sendPostBox = new PostBox<SmartPointer<OysterByte>>();
this->sendPostBox = new PostBox<CustomNetProtocol*>;
this->recvPostBox = NULL;
connection->SetBlockingMode(false);
@ -18,7 +18,7 @@ ThreadedClient::ThreadedClient()
ThreadedClient::ThreadedClient(unsigned int socket)
{
this->connection = new Connection(socket);
this->sendPostBox = new PostBox<SmartPointer<OysterByte>>();
this->sendPostBox = new PostBox<CustomNetProtocol*>;
this->recvPostBox = NULL;
connection->SetBlockingMode(false);
@ -26,10 +26,10 @@ ThreadedClient::ThreadedClient(unsigned int socket)
thread.Create(this, true);
}
ThreadedClient::ThreadedClient(IPostBox<Utility::DynamicMemory::SmartPointer<OysterByte>>* postBox, unsigned int socket)
ThreadedClient::ThreadedClient(IPostBox<CustomNetProtocol*>* postBox, unsigned int socket)
{
this->connection = new Connection(socket);
this->sendPostBox = new PostBox<SmartPointer<OysterByte>>;
this->sendPostBox = new PostBox<CustomNetProtocol*>;
this->recvPostBox = postBox;
connection->SetBlockingMode(false);
@ -51,9 +51,19 @@ ThreadedClient::~ThreadedClient()
}
}
void ThreadedClient::Send(SmartPointer<OysterByte>& byte)
void ThreadedClient::Send(CustomNetProtocol* protocol)
{
this->sendPostBox->PostMessage(byte);
this->sendPostBox->PostMessage(protocol);
}
bool ThreadedClient::IsConnected()
{
return connection->IsConnected();
}
void ThreadedClient::Disconnect()
{
connection->Disconnect();
}
int ThreadedClient::Send()
@ -62,9 +72,9 @@ int ThreadedClient::Send()
if(sendPostBox->IsFull())
{
SmartPointer<OysterByte> temp = new OysterByte;
sendPostBox->FetchMessage(temp);
errorCode = this->connection->Send(temp);
OysterByte temp;
sendPostBox->FetchMessage();
//errorCode = this->connection->Send(temp);
}
return errorCode;
@ -80,7 +90,7 @@ int ThreadedClient::Recv()
if(errorCode == 0)
{
stdMutex.lock();
recvPostBox->PostMessage(temp);
//recvPostBox->PostMessage(temp);
stdMutex.unlock();
}
@ -135,7 +145,7 @@ int ThreadedClient::Connect(unsigned short port, const char serverName[])
return 0;
}
void ThreadedClient::setRecvPostBox(IPostBox<SmartPointer<OysterByte>> *postBox)
void ThreadedClient::setRecvPostBox(IPostBox<CustomNetProtocol*> *postBox)
{
stdMutex.lock();
this->recvPostBox = postBox;

View File

@ -9,7 +9,6 @@
#include "PostBox.h"
#include "Connection.h"
#include "../../Misc/Thread/OysterThread.h"
#include "../../Misc/Thread/OysterMutex.h"
#include "../../Misc/Utilities.h"
#include <mutex>
@ -18,33 +17,39 @@ namespace Oyster
{
namespace Network
{
class CustomNetProtocol;
class OysterByte;
class ThreadedClient : public Thread::IThreadObject
{
public:
ThreadedClient();
ThreadedClient(unsigned int socket);
ThreadedClient(IPostBox<Utility::DynamicMemory::SmartPointer<OysterByte>> *postBox, unsigned int socket);
ThreadedClient(IPostBox<CustomNetProtocol*> *postBox, unsigned int socket);
virtual ~ThreadedClient();
void Send(Utility::DynamicMemory::SmartPointer<OysterByte>& byte);
void Send(CustomNetProtocol* protocol);
bool IsConnected();
int Connect(unsigned short port, const char serverName[]);
void setRecvPostBox(IPostBox<Utility::DynamicMemory::SmartPointer<OysterByte>> *postBox);
void Disconnect();
private:
void setRecvPostBox(IPostBox<CustomNetProtocol*> *postBox);
protected:
virtual int Send();
virtual int Recv();
//These functions should not be called by any other than the thread.
virtual void ThreadEntry();
virtual void ThreadExit();
virtual bool DoWork();
private:
protected:
Connection* connection;
IPostBox<Utility::DynamicMemory::SmartPointer<OysterByte>> *sendPostBox;
IPostBox<Utility::DynamicMemory::SmartPointer<OysterByte>> *recvPostBox;
IPostBox<CustomNetProtocol*> *sendPostBox;
IPostBox<CustomNetProtocol*> *recvPostBox;
Oyster::Thread::OysterThread thread;
std::mutex stdMutex;

View File

@ -1,74 +0,0 @@
#include "Translator.h"
using namespace Oyster::Network;
using namespace ::Protocols;
using namespace ::Messages;
void Translator::Pack( ProtocolHeader &header, Utility::DynamicMemory::SmartPointer<OysterByte> &bytes )
{
MessageHeader *message = NULL;
switch(header.packageType)
{
case PackageType_header:
message = new MessageHeader();
break;
case PackageType_test:
message = new MessageTest();
break;
case PackageType_player_pos:
message = new MessagePlayerPos();
break;
}
if(message != NULL)
{
message->Pack(header, *bytes);
delete message;
message = NULL;
}
}
void Translator::Unpack(ProtocolSet* set, Utility::DynamicMemory::SmartPointer<OysterByte> &bytes)
{
ProtocolHeader *header = new ProtocolHeader();
MessageHeader *message = new MessageHeader();
message->Unpack(*bytes, *header);
delete message;
message = NULL;
//Switch to the correct package.
set->type = (PackageType)header->packageType;
switch(set->type)
{
case PackageType_header:
message = new MessageHeader();
set->Protocol.pHeader = new ProtocolHeader;
message->Unpack(*bytes, *set->Protocol.pHeader);
break;
case PackageType_test:
message = new MessageTest();
set->Protocol.pTest = new ProtocolTest;
message->Unpack(*bytes, *set->Protocol.pTest);
break;
case PackageType_player_pos:
message = new MessagePlayerPos();
set->Protocol.pPlayerPos = new ProtocolPlayerPos;
message->Unpack(*bytes, *set->Protocol.pPlayerPos);
break;
}
if(message)
{
delete message;
}
delete header;
//return set;
}

View File

@ -1,32 +0,0 @@
#ifndef NETWORK_DEPENDENCIES_TRANSLATOR_H
#define NETWORK_DEPENDENCIES_TRANSLATOR_H
//////////////////////////////////
// Created by Sam Svensson 2013 //
//////////////////////////////////
#include "Messages/MessagesInclude.h"
#include "Protocols.h"
#include "ITranslate.h"
#include "OysterByte.h"
namespace Oyster
{
namespace Network
{
class Translator : public ITranslate
{
public:
Translator () { };
~Translator() { };
void Pack (Protocols::ProtocolHeader &header, Utility::DynamicMemory::SmartPointer<OysterByte> &bytes );
void Unpack (Protocols::ProtocolSet* set, Utility::DynamicMemory::SmartPointer<OysterByte> &bytes );
private:
};
}
}
#endif

View File

@ -1,3 +1,8 @@
#ifndef INCLUDE_WINSOCK_LIB
#define INCLUDE_WINSOCK_LIB
#pragma comment(lib, "ws2_32.lib")
#endif
#include "WinsockFunctions.h"
#include <WinSock2.h>

View File

@ -2,7 +2,6 @@
#include <WinSock2.h>
#include <vld.h>
#include "../NetworkDependencies/WinsockFunctions.h"
#include "..\NetworkDependencies\Translator.h"
#include "..\NetworkDependencies\Protocols.h"
#include "../NetworkDependencies/OysterByte.h"
#include "../../Misc/ThreadSafeQueue.h"
@ -44,6 +43,12 @@ int main()
}
chat(*client);
while(1)
{
}
delete client;
ShutdownWinSock();
@ -54,10 +59,10 @@ int main()
void chat(ThreadedClient &client)
{
Oyster::Network::Translator *t = new Oyster::Network::Translator();
/*Oyster::Network::Translator *t = new Oyster::Network::Translator();
IPostBox< SmartPointer<OysterByte >> *postBox = new PostBox< SmartPointer<OysterByte >>;
client.setRecvPostBox(postBox);
//client.setRecvPostBox(postBox);
SmartPointer<OysterByte> msgRecv = new OysterByte();
SmartPointer<OysterByte> msgSend = new OysterByte();
@ -80,7 +85,7 @@ void chat(ThreadedClient &client)
while(1)
{
//Fetch new messages from the postbox
if(postBox->FetchMessage(msgRecv))
//if(postBox->FetchMessage(msgRecv))
{
t->Unpack(set, msgRecv);
@ -93,14 +98,14 @@ void chat(ThreadedClient &client)
{
cout << "Sending to server." << endl;
timer.reset();
client.Send(msgSend);
//client.Send(msgSend);
}
Sleep(1);
}
delete postBox;
delete t;
delete set;
delete set;*/
}
void PrintOutMessage(ProtocolSet* set)

View File

@ -102,6 +102,8 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<DelayLoadDLLs>
</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -161,7 +163,6 @@
<ClCompile Include="TestClass.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="RecieverObject.h" />
<ClInclude Include="TestClass.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -23,9 +23,6 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="RecieverObject.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TestClass.h">
<Filter>Header Files</Filter>
</ClInclude>

View File

@ -1,19 +0,0 @@
#ifndef OYSTER_NETWORK_SERVER_RECIEVER_OBJECT_H
#define OYSTER_NETWORK_SERVER_RECIEVER_OBJECT_H
/////////////////////////////////////
// Created by Pontus Fransson 2013 //
/////////////////////////////////////
#include "../NetworkDependencies/Protocols.h"
#include "../NetworkDependencies/OysterByte.h"
#include "../../Misc/Utilities.h"
class RecieverObject
{
public:
virtual void ProcFunc(Utility::DynamicMemory::SmartPointer<Oyster::Network::OysterByte> msg) = 0;
};
#endif

View File

@ -1,14 +1,11 @@
#include <iostream>
#include <WinSock2.h>
#include <vector>
#include <vld.h>
#include "../NetworkDependencies/WinsockFunctions.h"
#include "TestClass.h"
#include "../NetworkAPI/Translator.h"
using namespace std;
void clientProc(Oyster::Network::NetworkClient* client);
int main()
{
if(!InitWinSock())
@ -16,39 +13,6 @@ int main()
cout << "errorMessage: unable to start winsock" << endl;
}
Test test;
cout << "Server" << endl;
test.mainLoop();
while(1)
{
//Fetch new clients from the postbox
/*
//Send a message every 1 seconds to all clients.
if(timer.getElapsedSeconds() > 1)
{
cout << "Sending to " << clients.size() << " clients." << endl;
timer.reset();
for(int i = 0; i < (int)clients.size(); i++)
{
clients.at(i)->Send(sendBuffer);
}
}*/
/*//Fetch messages
if(recvPostBox->FetchMessage(recvBuffer))
{
t.Unpack(set, recvBuffer);
//PrintOutMessage(set);
set->Release();
}*/
}
Sleep(1000);
system("pause");
return 0;

View File

@ -1,9 +1,8 @@
#include "TestClass.h"
#include "../../Misc/WinTimer.h"
#include <iostream>
/*
using namespace Oyster::Network;
using namespace ::Server;
using namespace ::Protocols;
using namespace Utility;
using namespace ::DynamicMemory;
@ -18,7 +17,6 @@ Test::Test()
NetworkServer::INIT_DESC initDesc;
initDesc.port = 9876;
initDesc.proc = NULL;
server.Init(initDesc);
server.Start();
@ -32,7 +30,7 @@ Test::Test()
test.matrix[i] = (float)i;
}
t.Pack(test, sendBuffer);
//t.Pack(test, sendBuffer);
}
Test::~Test()
@ -43,7 +41,7 @@ Test::~Test()
server.Stop();
}
void Test::ProcFunc(Utility::DynamicMemory::SmartPointer<Oyster::Network::OysterByte> msg)
void Test::ProcFunction(CustomNetProtocol& protocol)
{
return;
@ -83,4 +81,4 @@ void Test::PrintOutMessage(ProtocolSet* set)
cout << endl;
break;
}
}
}*/

View File

@ -1,16 +1,17 @@
#ifndef TEST_CLASS_H
#define TEST_CLASS_H
#include "RecieverObject.h"
/*
#include "../../Misc/Utilities.h"
#include "../NetworkDependencies/OysterByte.h"
#include "../NetworkDependencies/PostBox.h"
#include "../NetworkAPI/NetworkClient.h"
#include "../NetworkAPI/NetworkServer.h"
#include "../NetworkDependencies/Translator.h"
//#include "../NetworkDependencies/Translator.h"
#include "../NetworkAPI/CustomNetProtocol.h"
#include "../NetworkDependencies/Protocols.h"
#include <vector>
class Test : public RecieverObject
class Test
{
public:
Test();
@ -18,20 +19,20 @@ public:
void mainLoop();
virtual void ProcFunc(Utility::DynamicMemory::SmartPointer<Oyster::Network::OysterByte> msg);
virtual void ProcFunction(Oyster::Network::CustomNetProtocol& protocol);
void PrintOutMessage(Oyster::Network::Protocols::ProtocolSet* set);
private:
std::vector<Oyster::Network::NetworkClient*> clients;
Oyster::Network::IPostBox<Utility::DynamicMemory::SmartPointer<Oyster::Network::OysterByte>> *recvPostBox;
Oyster::Network::Translator t;
//Oyster::Network::Translator t;
Oyster::Network::Protocols::ProtocolPlayerPos test;
Utility::DynamicMemory::SmartPointer<Oyster::Network::OysterByte> sendBuffer;
Utility::DynamicMemory::SmartPointer<Oyster::Network::OysterByte> recvBuffer;
Oyster::Network::Server::NetworkServer server;
Oyster::Network::NetworkServer server;
};
*/
#endif