Added Handshake class

Fixed NetworkBuffer include
Fixed some data types
TcpClient: Added SendBytes, SetOnDisconnectCallback, SetOnConnectCallback, SetOnMessageCallback methods and made callback std::function's private and fixed some method implementations
Added AcceptConnection on TcpServer
Fixed TcpServer AddToClientsList
This commit is contained in:
xX-TheDoctor-Xx
2016-08-01 00:28:22 +01:00
parent e677fdeb59
commit 0ac8b4f6e8
18 changed files with 143 additions and 25 deletions

View File

@ -21,6 +21,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\include\Config.hpp" /> <ClInclude Include="..\..\include\Config.hpp" />
<ClInclude Include="..\..\include\Defs.hpp" /> <ClInclude Include="..\..\include\Defs.hpp" />
<ClInclude Include="..\..\include\Handshake.hpp" />
<ClInclude Include="..\..\include\Init.hpp" /> <ClInclude Include="..\..\include\Init.hpp" />
<ClInclude Include="..\..\include\NetworkBuffer.hpp" /> <ClInclude Include="..\..\include\NetworkBuffer.hpp" />
<ClInclude Include="..\..\include\NetworkMessage.hpp" /> <ClInclude Include="..\..\include\NetworkMessage.hpp" />
@ -33,6 +34,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\Config.cpp" /> <ClCompile Include="..\..\src\Config.cpp" />
<ClCompile Include="..\..\src\Handshake.cpp" />
<ClCompile Include="..\..\src\Init.cpp" /> <ClCompile Include="..\..\src\Init.cpp" />
<ClCompile Include="..\..\src\InitWindows.cpp"> <ClCompile Include="..\..\src\InitWindows.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>

View File

@ -42,6 +42,9 @@
<ClInclude Include="..\..\include\TcpServer.hpp"> <ClInclude Include="..\..\include\TcpServer.hpp">
<Filter>include</Filter> <Filter>include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\include\Handshake.hpp">
<Filter>include</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\Init.cpp"> <ClCompile Include="..\..\src\Init.cpp">
@ -77,6 +80,9 @@
<ClCompile Include="..\..\src\InitWindows.cpp"> <ClCompile Include="..\..\src\InitWindows.cpp">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\Handshake.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Text Include="..\..\TODO" /> <Text Include="..\..\TODO" />

25
include/Handshake.hpp Normal file
View File

@ -0,0 +1,25 @@
#ifndef HANDSHAKE_HPP
#define HANDSHAKE_HPP
#ifdef _MSC_VER
#pragma once
#endif
#include "Defs.hpp"
#include <vector>
struct Handshake
{
Handshake();
Handshake(uint16 id, byte con_code);
~Handshake();
static const std::vector<byte> &EncodeHandshake(const Handshake &handshake);
static Handshake &DecodeHandshake(const std::vector<byte> &bytes);
uint16 id;
byte con_code;
};
#endif

View File

@ -6,6 +6,7 @@
#endif #endif
#include "Defs.hpp" #include "Defs.hpp"
#include "Utility.hpp"
#include <vector> #include <vector>

View File

@ -12,7 +12,7 @@ struct NetworkMessage
{ {
NetworkMessage(); NetworkMessage();
NetworkMessage(const NetworkBuffer &buffer); NetworkMessage(const NetworkBuffer &buffer);
NetworkMessage(uint16 sender, byte distribution_mode, uint16 destination_id, byte tag, uint16 subject, NetworkBuffer buffer); NetworkMessage(uint16 sender, byte distribution_mode, uint16 destination_id, byte tag, byte subject, NetworkBuffer buffer);
~NetworkMessage(); ~NetworkMessage();
static const NetworkBuffer &EncodeMessage(const NetworkMessage &message); static const NetworkBuffer &EncodeMessage(const NetworkMessage &message);
@ -23,7 +23,7 @@ struct NetworkMessage
byte distribution_mode; byte distribution_mode;
uint16 destination_id; uint16 destination_id;
byte tag; byte tag;
uint16 subject; byte subject;
void *data; void *data;
bool valid = false; bool valid = false;

View File

@ -42,10 +42,11 @@ public:
//this is a more manual method with no callbacks //this is a more manual method with no callbacks
const NetworkMessage &ReceiveMessage(); const NetworkMessage &ReceiveMessage();
void SendMessage(const NetworkMessage &message); void SendMessage(const NetworkMessage &message);
void SendBytes(const std::vector<byte> &bytes);
std::function<void(uint16)> OnDisconnect; void SetOnDisconnectCallback(void (*func)(uint16));
std::function<void(uint16)> OnConnect; void SetOnConnectCallback(void (*func)(uint16));
std::function<void(uint16, byte, uint16, void*)> OnMessage; void SetOnMessageCallback(void (*func)(uint16, byte, byte, void*));
private: private:
const NetworkBuffer &receive_data_array(); const NetworkBuffer &receive_data_array();
@ -59,6 +60,10 @@ private:
bool initialized = false; bool initialized = false;
bool receive = false; bool receive = false;
std::function<void(uint16)> OnDisconnect;
std::function<void(uint16)> OnConnect;
std::function<void(uint16, byte, byte, void*)> OnMessage;
#ifdef _MSC_VER #ifdef _MSC_VER
SOCKET tcp_socket = INVALID_SOCKET; SOCKET tcp_socket = INVALID_SOCKET;
struct addrinfo *result = nullptr; struct addrinfo *result = nullptr;

View File

@ -24,12 +24,13 @@ public:
void Shutdown(); void Shutdown();
uint16 AllocateID(); uint16 AllocateID();
void AddToClientsList(const TcpClient &client); void AddToClientsList(TcpClient &client);
bool StartServer(bool accept_connections); bool StartServer(bool accept_connections);
void AcceptConnections(); void AcceptConnections();
void SendMessage(const NetworkMessage &message); void SendMessage(const NetworkMessage &message);
void RejectConnection(TcpClient &client); void RejectConnection(TcpClient &client);
void AcceptConnection(TcpClient &client);
std::function<void(const NetworkMessage &message)> OnMessage; std::function<void(const NetworkMessage &message)> OnMessage;

40
src/Handshake.cpp Normal file
View File

@ -0,0 +1,40 @@
#include "Handshake.hpp"
#include "Utility.hpp"
Handshake::Handshake()
{
id = -2;
}
Handshake::Handshake(uint16 id, byte con_code)
{
this->id = id;
this->con_code = con_code;
}
Handshake::~Handshake()
{
}
const std::vector<byte>& Handshake::EncodeHandshake(const Handshake & handshake)
{
std::vector<byte> handshake_bytes;
std::vector<byte> id = Utility::BitConverter::FromUint16(handshake.id);
std::vector<byte> con_mode = Utility::BitConverter::FromUint8(handshake.con_code);
handshake_bytes.insert(handshake_bytes.end(), id.begin(), id.end());
handshake_bytes.insert(handshake_bytes.end(), con_mode.begin(), con_mode.end());
return handshake_bytes;
}
Handshake & Handshake::DecodeHandshake(const std::vector<byte>& bytes)
{
Handshake handshake;
handshake.id = Utility::BitConverter::ToUint16(bytes);
handshake.con_code = Utility::BitConverter::ToUint8(bytes, 2);
return handshake;
}

View File

@ -1,5 +1,4 @@
#include "NetworkBuffer.hpp" #include "NetworkBuffer.hpp"
#include "Utility.hpp"
NetworkBuffer::NetworkBuffer() NetworkBuffer::NetworkBuffer()
{ {

View File

@ -9,7 +9,7 @@ NetworkMessage::NetworkMessage()
{ {
} }
NetworkMessage::NetworkMessage(uint16 sender, byte distribution_mode, uint16 destination_id, byte tag, uint16 subject, NetworkBuffer buffer) : NetworkMessage::NetworkMessage(uint16 sender, byte distribution_mode, uint16 destination_id, byte tag, byte subject, NetworkBuffer buffer) :
sender(sender), distribution_mode(distribution_mode), destination_id(destination_id), tag(tag), subject(subject), buffer(buffer) sender(sender), distribution_mode(distribution_mode), destination_id(destination_id), tag(tag), subject(subject), buffer(buffer)
{ {
} }
@ -52,7 +52,7 @@ const NetworkMessage &NetworkMessage::DecodeMessage(const NetworkBuffer &buffer)
message.distribution_mode = buffer.body[3]; message.distribution_mode = buffer.body[3];
message.destination_id = Utility::BitConverter::ToUint16(buffer.body, 4); message.destination_id = Utility::BitConverter::ToUint16(buffer.body, 4);
message.tag = buffer.body[6]; message.tag = buffer.body[6];
message.subject = Utility::BitConverter::ToUint16(buffer.body, 7); message.subject = Utility::BitConverter::ToUint8(buffer.body, 7);
message.buffer = buffer; message.buffer = buffer;
message.valid = message.sender != -2 && message.tag != CONNECT && message.tag != DISCONNECT; message.valid = message.sender != -2 && message.tag != CONNECT && message.tag != DISCONNECT;

View File

@ -3,6 +3,7 @@
#include "Config.hpp" #include "Config.hpp"
#include "NetworkBuffer.hpp" #include "NetworkBuffer.hpp"
#include "Tags.hpp" #include "Tags.hpp"
#include "Handshake.hpp"
#include <iostream> #include <iostream>
#include <thread> #include <thread>
@ -124,8 +125,15 @@ bool TcpClient::Connect()
uint16 connect_code = ::connect(tcp_socket, result->ai_addr, result->ai_addrlen); uint16 connect_code = ::connect(tcp_socket, result->ai_addr, result->ai_addrlen);
if (connect_code == SOCKET_ERROR) if (connect_code == SOCKET_ERROR)
return false; return false;
receive = true;
return true; NetworkBuffer message(receive_data_array());
Handshake handshake = Handshake::DecodeHandshake(message.body);
if (handshake.con_code == ConnectionCode::Accept)
{
receive = true;
return true;
}
return false;
} }
bool TcpClient::DataAvailable(uint16 &size) bool TcpClient::DataAvailable(uint16 &size)
@ -137,8 +145,8 @@ const NetworkBuffer &TcpClient::receive_data_array()
{ {
NetworkBuffer buffer; NetworkBuffer buffer;
uint16 body_size; uint16 temp;
if (DataAvailable(body_size)) if (DataAvailable(temp) && temp > 0)
{ {
if (!recv(tcp_socket, reinterpret_cast<char*>(&buffer.header[0]), 4, 0)) if (!recv(tcp_socket, reinterpret_cast<char*>(&buffer.header[0]), 4, 0))
//invalid header //invalid header
@ -148,10 +156,11 @@ const NetworkBuffer &TcpClient::receive_data_array()
return NetworkBuffer(); return NetworkBuffer();
uint32 body_size = Utility::BitConverter::ToUint32(buffer.header); uint32 body_size = Utility::BitConverter::ToUint32(buffer.header);
int32 body_received = recv(tcp_socket, reinterpret_cast<char*>(&buffer.body[0]), body_size, 0); int16 body_received = recv(tcp_socket, reinterpret_cast<char*>(&buffer.body[0]), body_size, 0);
if (body_received == SOCKET_ERROR || body_received != body_size || WSAGetLastError() != 0) if (body_received == SOCKET_ERROR || body_received != body_size || WSAGetLastError() != 0)
{ {
//there was a problem receiving the body of the message or theres no body to receive //there was a problem receiving the body of the message or theres no body to receive
return NetworkBuffer();
} }
return buffer; return buffer;
@ -188,7 +197,7 @@ void TcpClient::send_network_message(const NetworkMessage &message, TcpClient *c
{ {
NetworkBuffer buffer = NetworkMessage::EncodeMessage(message); NetworkBuffer buffer = NetworkMessage::EncodeMessage(message);
int32 bytes_sent = send(client->tcp_socket, reinterpret_cast<char*>(&buffer.body[0]), Utility::BitConverter::ToUint32(buffer.header), 0); int32 bytes_sent = send(client->tcp_socket, reinterpret_cast<char*>(&buffer.body[0]), Utility::BitConverter::ToUint32(buffer.header), 0);
if (bytes_sent == SOCKET_ERROR || bytes_sent != Utility::BitConverter::ToUint32(buffer.header) || WSAGetLastError() != 0) if (bytes_sent == SOCKET_ERROR || bytes_sent != Utility::BitConverter::ToInt32(buffer.header) || WSAGetLastError() != 0)
{ {
//something went wrong couldnt send anything/some data //something went wrong couldnt send anything/some data
} }
@ -198,3 +207,27 @@ void TcpClient::SendMessage(const NetworkMessage &message)
{ {
std::async(std::launch::async, &send_network_message, message, this); std::async(std::launch::async, &send_network_message, message, this);
} }
void TcpClient::SendBytes(const std::vector<byte>& bytes)
{
int32 bytes_sent = send(tcp_socket, reinterpret_cast<const char*>(&bytes[0]), bytes.size(), 0);
if (bytes_sent == SOCKET_ERROR || bytes_sent != bytes.size() || WSAGetLastError() != 0)
{
//something went wrong couldnt send anything/some data
}
}
void TcpClient::SetOnDisconnectCallback(void(*func)(uint16))
{
OnDisconnect = func;
}
void TcpClient::SetOnConnectCallback(void(*func)(uint16))
{
OnConnect = func;
}
void TcpClient::SetOnMessageCallback(void(*func)(uint16, byte, byte, void*))
{
OnMessage = func;
}

View File

@ -1,6 +1,7 @@
#include "TcpServer.hpp" #include "TcpServer.hpp"
#include "Config.hpp" #include "Config.hpp"
#include "Utility.hpp" #include "Utility.hpp"
#include "Handshake.hpp"
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -211,27 +212,32 @@ uint16 TcpServer::AllocateID() // this function is only used in the AddToClients
return 0; return 0;
} }
void TcpServer::AddToClientsList(const TcpClient & client_socket) void TcpServer::AddToClientsList(TcpClient & client_socket)
{ {
TcpClient client(client_socket);
uint16 id = AllocateID(); uint16 id = AllocateID();
if (id > 0) if (id > 0)
{ {
client.SetID(id); client_socket.SetID(id);
clients.emplace_back(client); clients.emplace_back(client_socket);
AcceptConnection(client_socket);
} }
else else
{ {
if (Config::GetUsingConsole()) if (Config::GetUsingConsole())
std::cout << "No available ID's" << std::endl; std::cout << "No available ID's" << std::endl;
RejectConnection(client); RejectConnection(client_socket);
} }
} }
void TcpServer::RejectConnection(TcpClient &client) void TcpServer::RejectConnection(TcpClient &client)
{ {
NetworkMessage message; Handshake handshake(client.GetID(), ConnectionCode::Reject);
message.sender = -1; client.SendBytes(Handshake::EncodeHandshake(handshake));
message.tag = Reject; // 0 for rejected connection client.Shutdown();
client.SendMessage(message); }
void TcpServer::AcceptConnection(TcpClient & client)
{
Handshake handshake(client.GetID(), ConnectionCode::Accept);
client.SendBytes(Handshake::EncodeHandshake(handshake));
} }