Started implementing broadcasting.

This commit is contained in:
Pontus Fransson 2014-02-23 18:38:20 +01:00
parent 8e9d1a4999
commit a0bf9e862a
7 changed files with 227 additions and 13 deletions

View File

@ -72,5 +72,38 @@ namespace GameLogic
Oyster::Network::CustomNetProtocol protocol; Oyster::Network::CustomNetProtocol protocol;
}; };
//#define protocol_Broadcast_Test 102
struct Protocol_Broadcast_Test :public Oyster::Network::CustomProtocolObject
{
int test;
Protocol_Broadcast_Test()
{
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[0].value.netShort = protocol_Broadcast_Test;
this->protocol[1].type = Oyster::Network::NetAttributeType_Int;
this->test = 0;
}
Protocol_Broadcast_Test(int test)
{
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[0].value.netShort = protocol_Broadcast_Test;
this->protocol[1].type = Oyster::Network::NetAttributeType_Int;
this->test = test;
}
Protocol_Broadcast_Test(Oyster::Network::CustomNetProtocol& p)
{
this->test = p[1].value.netInt;
}
Oyster::Network::CustomNetProtocol GetProtocol() override
{
this->protocol[1].value = this->test;
return protocol;
}
private:
Oyster::Network::CustomNetProtocol protocol;
};
} }
#endif //!GAMELOGIC_CONTROL_PROTOCOLS_H #endif //!GAMELOGIC_CONTROL_PROTOCOLS_H

View File

@ -20,6 +20,7 @@
#define protocol_GeneralMIN 100 #define protocol_GeneralMIN 100
#define protocol_General_Status 100 #define protocol_General_Status 100
#define protocol_General_Text 101 #define protocol_General_Text 101
#define protocol_Broadcast_Test 102
#define protocol_GeneralMAX 199 #define protocol_GeneralMAX 199

View File

@ -10,6 +10,8 @@
#include "..\GameLobby.h" #include "..\GameLobby.h"
#include "..\GameSession.h" #include "..\GameSession.h"
#include "..\GameProtocols\GeneralProtocols.h"
#include <NetworkServer.h> #include <NetworkServer.h>
#include <NetworkClient.h> #include <NetworkClient.h>
@ -47,6 +49,13 @@ DanBiasServerReturn GameServerAPI::ServerInitiate(const ServerInitDesc& desc)
ServerOptions opt; ServerOptions opt;
opt.mainOptions.listenPort = desc.listenPort; opt.mainOptions.listenPort = desc.listenPort;
opt.mainOptions.ownerSession = &lobby; opt.mainOptions.ownerSession = &lobby;
GameLogic::Protocol_Broadcast_Test broadcastMessage(2);
opt.broadcastOptions.broadcast = true;
opt.broadcastOptions.broadcastInterval = 1.0f;
opt.broadcastOptions.broadcastMessage = broadcastMessage.GetProtocol();
if(server.Init(opt) == NetworkServer::ServerReturnCode_Error) if(server.Init(opt) == NetworkServer::ServerReturnCode_Error)
{ {
return DanBiasServerReturn_Error; return DanBiasServerReturn_Error;

View File

@ -13,6 +13,7 @@
#include "CustomNetProtocol.h" #include "CustomNetProtocol.h"
#include "NetworkSession.h" #include "NetworkSession.h"
#include "../NetworkDependencies/ConnectionUDP.h"
#include "../NetworkDependencies/Connection.h" #include "../NetworkDependencies/Connection.h"
#include "../NetworkDependencies/PostBox.h" #include "../NetworkDependencies/PostBox.h"
#include "../NetworkDependencies/WinsockFunctions.h" #include "../NetworkDependencies/WinsockFunctions.h"
@ -56,8 +57,11 @@ struct NetworkClient::PrivateData : public IThreadObject
ThreadSafeQueue<CustomNetProtocol> sendQueue; ThreadSafeQueue<CustomNetProtocol> sendQueue;
ThreadSafeQueue<NetEvent<NetworkClient*, NetworkClient::ClientEventArgs>> recieveQueue; ThreadSafeQueue<NetEvent<NetworkClient*, NetworkClient::ClientEventArgs>> recieveQueue;
//Broadcast
ConnectionUDP broadcastConnection;
//Testing for eventSelect. //Testing for eventSelect.
HANDLE socketEvents[2]; HANDLE socketEvents[3];
HANDLE shutdownEvent; HANDLE shutdownEvent;
//The OysterByte each message is packed in. //The OysterByte each message is packed in.
@ -101,6 +105,7 @@ struct NetworkClient::PrivateData : public IThreadObject
shutdownEvent = CreateEvent(NULL, true, false, NULL); shutdownEvent = CreateEvent(NULL, true, false, NULL);
socketEvents[0] = WSACreateEvent(); socketEvents[0] = WSACreateEvent();
socketEvents[1] = WSACreateEvent(); socketEvents[1] = WSACreateEvent();
socketEvents[2] = WSACreateEvent();
if(socketEvents[0] == WSA_INVALID_EVENT) if(socketEvents[0] == WSA_INVALID_EVENT)
{ {
@ -111,12 +116,18 @@ struct NetworkClient::PrivateData : public IThreadObject
{ {
//Error //Error
} }
if(WSAEventSelect(this->broadcastConnection.GetSocket(), socketEvents[2], FD_READ) == SOCKET_ERROR)
{
//Error
}
} }
void ThreadExit() void ThreadExit()
{ {
WSACloseEvent(socketEvents[0]); WSACloseEvent(socketEvents[0]);
WSACloseEvent(socketEvents[1]); WSACloseEvent(socketEvents[1]);
WSACloseEvent(socketEvents[2]);
CloseHandle(shutdownEvent); CloseHandle(shutdownEvent);
} }
@ -128,7 +139,7 @@ struct NetworkClient::PrivateData : public IThreadObject
{ {
if(!this->connection.IsConnected()) return false; if(!this->connection.IsConnected()) return false;
int result = WSAWaitForMultipleEvents(2, socketEvents, FALSE, 100, FALSE) - WSA_WAIT_EVENT_0; int result = WSAWaitForMultipleEvents(3, socketEvents, FALSE, 100, FALSE) - WSA_WAIT_EVENT_0;
if(result == 0) if(result == 0)
{ {
WSAEnumNetworkEvents(this->connection.GetSocket(), socketEvents[0], &wsaEvents); WSAEnumNetworkEvents(this->connection.GetSocket(), socketEvents[0], &wsaEvents);
@ -156,11 +167,64 @@ struct NetworkClient::PrivateData : public IThreadObject
SendBuffer(); SendBuffer();
} }
} }
else if(result == 2)
{
WSAEnumNetworkEvents(this->broadcastConnection.GetSocket(), socketEvents[2], &wsaEvents);
if((wsaEvents.lNetworkEvents & FD_READ) && (wsaEvents.iErrorCode[FD_READ_BIT] == 0))
{
//Recieve a message
}
}
if(broadcastConnection.GetSocket() > 0)
{
RecvUDP();
}
} }
return false; return false;
} }
void RecvUDP()
{
int errorCode = -1;
errorCode = this->broadcastConnection.Recieve(tempMessage);
if(errorCode == 0 && tempMessage.GetSize())
{
CustomNetProtocol protocol;
bool ok = this->translator.Unpack(protocol, tempMessage);
//Check if the protocol was unpacked correctly
if(ok)
{
CEA parg;
parg.type = CEA::EventType_ProtocolRecieved;
parg.data.protocol = protocol;
NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e;
e.sender = this->parent;
e.args.data.protocol = parg.data.protocol;
e.args.type = parg.type;
this->recieveQueue.Push(e);
if(this->outputEvent)
{
printf("\t(ID: %i | IP: %s | Protocol: %i) Message recieved!\n", this->ID, this->connection.GetIpAddress().c_str(), protocol[0].value.netShort);
}
}
else
{
if(this->outputEvent)
{
printf("\t(ID: %i | IP: %s) Failed to unpack CustomNetProtocol!\n", this->ID, this->connection.GetIpAddress().c_str());
}
}
tempMessage.Clear();
}
}
void SendBuffer() void SendBuffer()
{ {
if(bufferedSend.GetSize() > 0) if(bufferedSend.GetSize() > 0)
@ -483,6 +547,9 @@ bool NetworkClient::Connect(unsigned short port, const char serverIP[])
if(!this->privateData) if(!this->privateData)
this->privateData = new PrivateData(); this->privateData = new PrivateData();
this->privateData->broadcastConnection.InitiateClient();
this->privateData->broadcastConnection.Connect(port, "0.0.0.0");
int result = this->privateData->connection.Connect(port, serverIP, true); int result = this->privateData->connection.Connect(port, serverIP, true);
//Connect has succeeded //Connect has succeeded

View File

@ -10,6 +10,8 @@
#include "NetworkServer.h" #include "NetworkServer.h"
#include "Translator.h"
#include "../NetworkDependencies/ConnectionUDP.h"
#include "../NetworkDependencies/Listener.h" #include "../NetworkDependencies/Listener.h"
#include "../NetworkDependencies/PostBox.h" #include "../NetworkDependencies/PostBox.h"
#include "../NetworkDependencies/WinsockFunctions.h" #include "../NetworkDependencies/WinsockFunctions.h"
@ -81,7 +83,14 @@ public:
, port(-1) , port(-1)
, broadcast(0) , broadcast(0)
, broadcastTime(1.0f, 0.0f) , broadcastTime(1.0f, 0.0f)
{ } {
InitWinSock();
serverOptions.broadcastOptions.broadcastInterval = 1.0f;
serverOptions.broadcastOptions.broadcast = true;
broadcastMessage.Resize(MAX_NETWORK_MESSAGE_SIZE);
broadcastConnection.InitiateBroadcastServer(15151, "255.255.255.255");
}
~PrivateData() ~PrivateData()
{ {
if(listener) if(listener)
@ -91,6 +100,12 @@ public:
} }
} }
void SendBroadcast()
{
broadcastConnection.Send(broadcastMessage);
}
bool DoWork(); bool DoWork();
public: public:
@ -106,6 +121,11 @@ public:
int port; int port;
bool broadcast; bool broadcast;
ServerOptions serverOptions;
ConnectionUDP broadcastConnection;
OysterByte broadcastMessage;
TimeInstance broadcastTime; TimeInstance broadcastTime;
Utility::WinTimer serverTimer; Utility::WinTimer serverTimer;
@ -113,11 +133,17 @@ public:
bool NetworkServer::PrivateData::DoWork() bool NetworkServer::PrivateData::DoWork()
{ {
if(broadcast) if(serverOptions.broadcastOptions.broadcast)
{ {
if( (this->serverTimer.getElapsedSeconds() - this->broadcastTime.previous) >= this->broadcastTime.length ) if( (this->serverTimer.getElapsedSeconds() - this->broadcastTime.previous) >= this->broadcastTime.length )
{ {
Broadcast(); broadcastMessage.Clear();
Translator t;
t.Pack(broadcastMessage, serverOptions.broadcastOptions.broadcastMessage);
serverTimer.reset();
//Broadcast();
SendBroadcast();
} }
} }
@ -197,6 +223,8 @@ NetworkServer::ServerReturnCode NetworkServer::Init(ServerOptions& options)
return NetworkServer::ServerReturnCode_Error; return NetworkServer::ServerReturnCode_Error;
} }
this->privateData->serverOptions.broadcastOptions = options.broadcastOptions;
this->privateData->isInitiated = true; this->privateData->isInitiated = true;
this->privateData->isReleased = false; this->privateData->isReleased = false;
return NetworkServer::ServerReturnCode_Sucess; return NetworkServer::ServerReturnCode_Sucess;
@ -319,6 +347,35 @@ int NetworkServer::GetPort()
return this->privateData->port; return this->privateData->port;
} }
/***************************************
Broadcast functions
***************************************/
//Set broadcast settings.
void NetworkServer::SetBroadcast(CustomNetProtocol& broadcastMessage, float interval, bool enable)
{
this->privateData->serverOptions.broadcastOptions.broadcast = enable;
this->privateData->serverOptions.broadcastOptions.broadcastMessage = broadcastMessage;
this->privateData->serverOptions.broadcastOptions.broadcastInterval = interval;
Translator t;
t.Pack(this->privateData->broadcastMessage, broadcastMessage);
}
//Set broadcast settings.
void NetworkServer::SetBroadcastMessage(CustomNetProtocol& broadcastMessage)
{
this->privateData->serverOptions.broadcastOptions.broadcastMessage = broadcastMessage;
Translator t;
t.Pack(this->privateData->broadcastMessage, broadcastMessage);
}
//Enable/disable broadcast.
void NetworkServer::SetBroadcast(bool enable)
{
this->privateData->serverOptions.broadcastOptions.broadcast = enable;
}
//Set interval between each broadcast message in seconds.
void NetworkServer::SetBroadcastInterval(float interval)
{
this->privateData->serverOptions.broadcastOptions.broadcastInterval = interval;
}

View File

@ -41,8 +41,24 @@ int ConnectionUDP::Connect(unsigned short port, const char serverName[])
} }
//this->Address = htonl(0xffffffff);
this->Address = *(unsigned long*)hostEnt->h_addr; this->Address = *(unsigned long*)hostEnt->h_addr;
this->port = htons(this->port); this->port = htons(this->port);
if(this->Address == 0)
{
sockaddr_in addr;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_family = AF_INET;
addr.sin_port = this->port;
int result = bind(socket, (const sockaddr*)&addr, sizeof(addr));
if(result)
{
int a = 0;
}
}
return 0; return 0;
} }
@ -89,19 +105,46 @@ int ConnectionUDP::InitiateClient()
return InitiateSocket(); return InitiateSocket();
} }
int ConnectionUDP::InitiateBroadcast(unsigned short port) int ConnectionUDP::InitiateBroadcastServer(unsigned short port, const char serverName[])
{ {
int result = InitiateSocket(); int result = InitiateSocket();
int flag = 1; int flag = 1;
result = setsockopt(this->socket, /* socket affected */ result = setsockopt(this->socket, SOL_SOCKET, SO_BROADCAST, (char *) &flag, sizeof(flag));
SOL_SOCKET, /* set option at TCP level */
SO_BROADCAST, /* name of option */
(char *) &flag, /* the cast is historical cruft */
sizeof(flag)); /* length of option value */
if (result < 0) if (result < 0)
return -1; return -1;
closed = false;
stillSending = true;
struct hostent *hostEnt;
if((hostEnt = gethostbyname(serverName)) == NULL)
{
return SOCKET_ERROR;
}
this->Address = *(unsigned long*)hostEnt->h_addr;
this->port = htons(port);
return 0;
}
int ConnectionUDP::InitiateBroadcastClient(unsigned short port)
{
int result = InitiateSocket();
struct sockaddr_in recvAddr;
recvAddr.sin_family = AF_INET;
recvAddr.sin_addr.s_addr = INADDR_ANY;
recvAddr.sin_port = htons(port);
if(bind(this->socket, (sockaddr*)&recvAddr, sizeof(recvAddr)) == SOCKET_ERROR)
{
closesocket(this->socket);
return SOCKET_ERROR;
}
return result;
} }
int ConnectionUDP::Send(OysterByte &bytes) int ConnectionUDP::Send(OysterByte &bytes)

View File

@ -22,13 +22,17 @@ namespace Oyster
virtual int InitiateServer( unsigned short port ); virtual int InitiateServer( unsigned short port );
virtual int InitiateClient(); virtual int InitiateClient();
virtual int InitiateBroadcast(unsigned short port); virtual int InitiateBroadcastServer(unsigned short port, const char serverName[]);
virtual int InitiateBroadcastClient(unsigned short port);
virtual int Send ( OysterByte &byte ); virtual int Send ( OysterByte &byte );
virtual int Recieve( OysterByte &byte ); virtual int Recieve( OysterByte &byte );
virtual int Connect( unsigned short port, const char serverName[] ); virtual int Connect( unsigned short port, const char serverName[] );
//Doesn't do anything now.
virtual int Reconnect() { return 0; }
virtual int Disconnect(); virtual int Disconnect();
bool IsSending(); bool IsSending();