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:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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>
|
||||||
|
|||||||
@ -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
25
include/Handshake.hpp
Normal 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
|
||||||
@ -6,6 +6,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Defs.hpp"
|
#include "Defs.hpp"
|
||||||
|
#include "Utility.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
40
src/Handshake.cpp
Normal 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;
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
#include "NetworkBuffer.hpp"
|
#include "NetworkBuffer.hpp"
|
||||||
#include "Utility.hpp"
|
|
||||||
|
|
||||||
NetworkBuffer::NetworkBuffer()
|
NetworkBuffer::NetworkBuffer()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@ -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));
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user