Updated TODO list

Removed windows specific files since the code is the same for linux
UdpClient: added basic methods to interact with the variables of that class, added initialization and started with sending and receiving messages
UdpServer: added initialization and basic variables
Utility: added a bunch of methods to the StringConverter utility class
VoidNetClientAPI: SendMessage now checks if message is not an handshake
This commit is contained in:
xX-TheDoctor-Xx
2016-09-08 00:36:45 +01:00
parent 74d9d5db87
commit 3e97c0da6d
20 changed files with 593 additions and 318 deletions

7
TODO
View File

@ -1,13 +1,14 @@
initialization code for other operating systems - currently VoidNet only supports windows
initialization code for tcp client and tcp server for other operating systems - currently windows only
handle SendNetworkMessage errors for windows
handle ReceiveDataArray errors for windows
revamped BitConverter class
new StringConverter class
IPUtil class for other os's
maybe i should implement error codes
maybe i should implement error codes and exceptions
plugin system - idk how im going to implement it yet
maybe i should use virtual methods for the server and client, maybe...
TcpServer::SendMessage rework

View File

@ -29,6 +29,7 @@
<ClInclude Include="..\..\include\TcpClient.hpp" />
<ClInclude Include="..\..\include\TcpServer.hpp" />
<ClInclude Include="..\..\include\UdpClient.hpp" />
<ClInclude Include="..\..\include\UdpServer.hpp" />
<ClInclude Include="..\..\include\Utility.hpp" />
<ClInclude Include="..\..\include\VoidNetClient.hpp" />
<ClInclude Include="..\..\include\VoidNetServer.hpp" />
@ -44,17 +45,9 @@
<ClCompile Include="..\..\src\NetworkMessage.cpp" />
<ClCompile Include="..\..\src\Serializer.cpp" />
<ClCompile Include="..\..\src\TcpClient.cpp" />
<ClCompile Include="..\..\src\TcpClientWindows.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\TcpServer.cpp" />
<ClCompile Include="..\..\src\TcpServerWindows.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\UdpClient.cpp" />
<ClCompile Include="..\..\src\UdpClientWindows.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\UdpServer.cpp" />
<ClCompile Include="..\..\src\Utility.cpp" />
<ClCompile Include="..\..\src\VoidNetClient.cpp" />
</ItemGroup>

View File

@ -48,14 +48,14 @@
<ClInclude Include="..\..\include\UdpClient.hpp">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\UdpServer.hpp">
<Filter>include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\Init.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\TcpClientWindows.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\Utility.cpp">
<Filter>src</Filter>
</ClCompile>
@ -74,9 +74,6 @@
<ClCompile Include="..\..\src\VoidNetClient.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\TcpServerWindows.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\TcpServer.cpp">
<Filter>src</Filter>
</ClCompile>
@ -92,7 +89,7 @@
<ClCompile Include="..\..\src\UdpClient.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\UdpClientWindows.cpp">
<ClCompile Include="..\..\src\UdpServer.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>

View File

@ -243,6 +243,6 @@ enum InternalTags
DisconnectTag = 255,
};
#define IS_HANDSHAKE(name) name.subject == 1 && (name.tag == DisconnectTag || name.tag == ConnectTag || name.tag == Accept || name.tag == Close || name.tag == Reject)
#define IS_HANDSHAKE(name) name.subject == 1 || (name.tag == DisconnectTag || name.tag == ConnectTag || name.tag == Accept || name.tag == Close || name.tag == Reject)
#endif // DEFS_HPP

View File

@ -10,8 +10,16 @@
struct Initialization
{
static bool initialize();
static bool Initialize();
#ifdef _MSC_VER
const WSADATA &GetData();
#endif
private:
#ifdef _MSC_VER
static WSADATA wsa_data;
#endif
};
#endif

View File

@ -7,6 +7,7 @@
#include <string>
#include <vector>
#include <functional>
#include <future>
#ifdef _MSC_VER
#pragma once
@ -39,18 +40,24 @@ struct TcpClient
//this is a more manual method with no callbacks
const NetworkMessage &ReceiveMessage();
void SendMessage(const NetworkMessage &message);
void SendBytes(const std::vector<byte> &bytes);
void SendBytes(byte *bytes, uint32 lenght);
std::future<bool> SendMessage(const NetworkMessage &message);
bool SendBytes(const std::vector<byte> &bytes);
bool SendBytes(byte *bytes, uint32 lenght);
void SetOnDisconnectCallback(void (*func)(uint16));
void SetOnConnectCallback(void (*func)(uint16));
void SetOnMessageCallback(void (*func)(uint16, byte, byte, void*));
static const TcpClient &DefaultTcpClient();
private:
TcpClient();
const NetworkBuffer &receive_data_array();
static void receive_data(TcpClient *client);
static void send_network_message(const NetworkMessage &message, TcpClient *client);
static bool send_network_message(const NetworkMessage &message, TcpClient *client);
bool initialize(const std::string &ip, uint16 port = default_client_port);
uint16 id = -2;
@ -63,11 +70,9 @@ private:
std::function<void(uint16)> OnConnect;
std::function<void(uint16, byte, byte, void*)> OnMessage;
#ifdef _MSC_VER
SOCKET tcp_socket = INVALID_SOCKET;
struct addrinfo *result = nullptr;
struct addrinfo hints;
#endif
};
#endif

View File

@ -22,7 +22,7 @@ struct TcpServer
bool StartServer(bool accept_connections); // if accept_connections is false the user must call the funcion AcceptConnections()
void AcceptConnections();
void SendMessage(const NetworkMessage &message);
bool SendMessage(const NetworkMessage &message);
void RejectConnection(TcpClient &client);
void AcceptConnection(uint16 client);
@ -56,11 +56,9 @@ private:
std::vector<TcpClient> clients;
#ifdef _MSC_VER
SOCKET server_tcp_socket = INVALID_SOCKET;
struct addrinfo *result = nullptr;
struct addrinfo hints;
#endif
};
#endif

View File

@ -9,11 +9,49 @@
#include "NetworkMessage.hpp"
#include <string>
#include <vector>
#include <functional>
#include <future>
struct UdpClient
{
UdpClient(const SOCKET &socket);
UdpClient(const std::string &ip);
UdpClient(const std::string &ip, uint16 = default_client_port);
~UdpClient();
void Shutdown();
const std::string &GetIP();
void SetIP(const std::string &ip);
uint16 GetPort();
void SetPort(uint16 port);
uint16 GetID();
void SetID(uint16 id);
std::future<bool> SendMessage(const NetworkMessage &message);
bool SendBytes(const std::vector<byte> &bytes);
bool SendBytes(byte *bytes, uint32 lenght);
private:
bool initialize(const std::string &ip, uint16 port = default_client_port);
static bool send_network_message(const NetworkMessage &message, UdpClient *client);
uint16 id = -2;
std::string ip;
uint16 port = 0;
bool initialized = false;
bool receive = false;
std::function<void(uint16)> OnDisconnect;
std::function<void(uint16)> OnConnect;
std::function<void(uint16, byte, byte, void*)> OnMessage;
SOCKET udp_socket = INVALID_SOCKET;
};
#endif

34
include/UdpServer.hpp Normal file
View File

@ -0,0 +1,34 @@
#ifndef UDP_SERVER_HPP
#define UDP_SERVER_HPP
#ifdef _MSC_VER
#pragma once
#endif
#include "Defs.hpp"
#include "UdpClient.hpp"
#include <string>
#include <vector>
struct UdpServer
{
private:
bool initialize(uint16 port = default_server_port);
uint16 allocate_id();
void shutdown_internal();
bool initialized = false;
bool running = false;
uint16 max_connections = 0;
std::vector<UdpClient> clients;
SOCKET server_udp_socket = INVALID_SOCKET;
struct sockaddr_in server;
};
#endif

View File

@ -56,6 +56,15 @@ struct Utility
static const std::string &ToString(int64 value);
static const std::string &ToString(const std::vector<byte> &bytes);
static uint8 ToUint8(const std::string &str);
static uint16 ToUint16(const std::string &str);
static uint32 ToUint32(const std::string &str);
static uint64 ToUint64(const std::string &str);
static int8 ToInt8(const std::string &str);
static int16 ToInt16(const std::string &str);
static int32 ToInt32(const std::string &str);
static int64 ToInt64(const std::string &str);
static const std::vector<byte> &ToBytes(const std::string &str);
static const std::string &ToString(const std::vector<byte> &bytes, uint16 start_index = 0, uint16 lenght = 0);
@ -64,6 +73,11 @@ struct Utility
static std::vector<std::string> Split(const std::string &str, const std::string &delimiter);
};
struct IPUtil
{
static bool ValidIPV4(const std::string &ip);
};
struct ConfigReader
{
void ReadConfig(const std::string &file_name);

View File

@ -3,7 +3,7 @@
#include <iostream>
bool Initialization::initialize()
bool Initialization::Initialize()
{
uint16 code = WSAStartup(MAKEWORD(2, 2), &wsa_data);
if (code != 0)
@ -14,3 +14,8 @@ bool Initialization::initialize()
}
return true;
}
const WSADATA &Initialization::GetData()
{
return wsa_data;
}

View File

@ -1,8 +1,12 @@
#include "TcpClient.hpp"
#include "NetworkBuffer.hpp"
#include "Utility.hpp"
#include "Config.hpp"
#include "Handshake.hpp"
#include <string>
#include <future>
#include <iostream>
TcpClient::TcpClient(const std::string &ip) : port(default_client_port)
{
@ -56,7 +60,7 @@ void TcpClient::receive_data(TcpClient *client)
{
if (message.tag == ConnectTag) // some user has connected - not us, never
std::async(std::launch::async, client->OnConnect, message.sender);
else if (message.tag == DisconnectTag || message.tag == Close) // some user has disconnected
else if (message.tag == DisconnectTag || message.tag == Close) // some user has disconnected, it can be us
std::async(std::launch::async, client->OnDisconnect, message.sender);
}
else
@ -75,9 +79,9 @@ const NetworkMessage & TcpClient::ReceiveMessage()
return receive_data_array();
}
void TcpClient::SendMessage(const NetworkMessage &message)
std::future<bool> TcpClient::SendMessage(const NetworkMessage &message)
{
std::async(std::launch::async, &send_network_message, message, this);
return std::async(std::launch::async, &send_network_message, message, this);
}
void TcpClient::SetOnDisconnectCallback(void(*func)(uint16))
@ -95,6 +99,146 @@ void TcpClient::SetOnMessageCallback(void(*func)(uint16, byte, byte, void*))
OnMessage = func;
}
#ifdef _MSC_VER
#include "TcpClientWindows.cpp"
#endif
const TcpClient & TcpClient::DefaultTcpClient()
{
return TcpClient();
}
TcpClient::TcpClient(const SOCKET & socket)
{
tcp_socket = socket;
}
bool TcpClient::initialize(const std::string &ip, uint16 port)
{
if (Utility::IPUtil::ValidIPV4(ip) || port == 0)
return false;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
uint16 code = getaddrinfo(ip.c_str(), std::to_string(port).c_str(), &hints, &result);
if (code != 0)
{
if (Config::GetUsingConsole())
std::cerr << code << std::endl; // display more info
WSACleanup();
return false;
}
tcp_socket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (tcp_socket == INVALID_SOCKET)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
freeaddrinfo(result);
WSACleanup();
return false;
}
return initialized = true;
}
TcpClient::~TcpClient()
{
freeaddrinfo(result);
WSACleanup();
Utility::Delete(result);
}
void TcpClient::Shutdown()
{
Handshake handshake(id, Close, Server);
SendMessage(Handshake::HandshakeToNetworkMessage(handshake));
uint16 code = closesocket(tcp_socket);
if (code == SOCKET_ERROR)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
}
WSACleanup();
}
bool TcpClient::Connect()
{
if (!initialized)
{
if (ip.size() == 0 || std::count(ip.begin(), ip.end(), '.') != 4 && port == 0 && !initialize(ip, port))
return false;
}
else return false;
uint16 connect_code = connect(tcp_socket, result->ai_addr, result->ai_addrlen);
if (connect_code == SOCKET_ERROR)
return false;
NetworkMessage message(receive_data_array());
if (IS_HANDSHAKE(message))
{
if (message.tag == Accept)
{
receive = true;
OnConnect(message.sender);
return true;
}
}
return false;
}
bool TcpClient::DataAvailable(int32 &size)
{
return ioctlsocket(tcp_socket, FIONREAD, reinterpret_cast<u_long*>(size)) != NO_ERROR && size > 0;
}
const NetworkBuffer &TcpClient::receive_data_array()
{
NetworkBuffer buffer;
int32 temp;
if (DataAvailable(temp) && temp > sizeof(int32))
{
byte *header = new byte[sizeof(int32)]();
if (recv(tcp_socket, reinterpret_cast<char*>(header), sizeof(int32), 0) != sizeof(int32))
return NetworkBuffer();
buffer.header = std::vector<byte>(header, header + sizeof(int32));
}
else
return NetworkBuffer();
int32 body_size = Utility::BitConverter::ToInt32(buffer.header);
byte *body = new byte[body_size]();
int16 received_bytes = recv(tcp_socket, reinterpret_cast<char*>(body), body_size, 0);
if (received_bytes == SOCKET_ERROR || received_bytes != body_size || WSAGetLastError() != 0)
return NetworkBuffer();
buffer.body = std::vector<byte>(body, body + body_size);
buffer.valid = true;
return buffer;
}
bool TcpClient::send_network_message(const NetworkMessage &message, TcpClient *client)
{
NetworkBuffer buffer = NetworkMessage::EncodeMessage(message);
int32 lenght = Utility::BitConverter::ToInt32(buffer.header);
int32 bytes_sent = send(client->tcp_socket, reinterpret_cast<char*>(buffer.body.data()), lenght, 0);
return bytes_sent == SOCKET_ERROR || bytes_sent != lenght || WSAGetLastError() != 0;
}
bool TcpClient::SendBytes(const std::vector<byte>& bytes)
{
int32 bytes_sent = send(tcp_socket, reinterpret_cast<const char*>(bytes.data()), bytes.size(), 0);
if (bytes_sent == SOCKET_ERROR || bytes_sent != bytes.size() || WSAGetLastError() != 0)
{
//something went wrong couldnt send anything/some data
}
}
bool TcpClient::SendBytes(byte * bytes, uint32 size)
{
int32 bytes_sent = send(tcp_socket, reinterpret_cast<const char*>(bytes), size, 0);
return bytes_sent == SOCKET_ERROR || bytes_sent != size || WSAGetLastError() != 0;
}

View File

@ -1,156 +0,0 @@
#include "TcpClient.hpp"
#include "Utility.hpp"
#include "Config.hpp"
#include "Handshake.hpp"
#include <iostream>
TcpClient::TcpClient(const SOCKET & socket)
{
tcp_socket = socket;
}
bool TcpClient::initialize(const std::string &ip, uint16 port)
{
if (ip.size() == 0 || std::count(ip.begin(), ip.end(), '.') != 4 || port == 0)
return false;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
uint16 code = getaddrinfo(ip.c_str(), std::to_string(port).c_str(), &hints, &result);
if (code != 0)
{
if (Config::GetUsingConsole())
std::cerr << code << std::endl; // display more info
WSACleanup();
return false;
}
tcp_socket = ::socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (tcp_socket == INVALID_SOCKET)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
freeaddrinfo(result);
WSACleanup();
return false;
}
return initialized = true;
}
TcpClient::~TcpClient()
{
freeaddrinfo(result);
WSACleanup();
Utility::Delete(result);
}
void TcpClient::Shutdown()
{
Handshake handshake(id, Close, Server);
SendMessage(Handshake::HandshakeToNetworkMessage(handshake));
uint16 code = closesocket(tcp_socket);
if (code == SOCKET_ERROR)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
}
closesocket(tcp_socket);
WSACleanup();
}
bool TcpClient::Connect()
{
if (!initialized)
{
if (ip.size() == 0 || std::count(ip.begin(), ip.end(), '.') != 4 && port == 0 && !initialize(ip, port))
return false;
}
else return false;
uint16 connect_code = connect(tcp_socket, result->ai_addr, result->ai_addrlen);
if (connect_code == SOCKET_ERROR)
return false;
NetworkMessage message(receive_data_array());
if (IS_HANDSHAKE(message))
{
if (message.tag == Accept)
{
receive = true;
OnConnect(message.sender);
return true;
}
}
return false;
}
bool TcpClient::DataAvailable(int32 &size)
{
return ioctlsocket(tcp_socket, FIONREAD, reinterpret_cast<u_long*>(size)) != NO_ERROR && size > 0;
}
const NetworkBuffer &TcpClient::receive_data_array()
{
NetworkBuffer buffer;
int32 temp;
if (DataAvailable(temp) && temp > sizeof(int32))
{
byte *header = new byte[sizeof(int32)]();
if (recv(tcp_socket, reinterpret_cast<char*>(header), sizeof(int32), 0) != sizeof(int32))
//invalid header
return NetworkBuffer();
buffer.header = std::vector<byte>(header, header + sizeof(int32));
}
else
return NetworkBuffer();
int32 body_size = Utility::BitConverter::ToInt32(buffer.header);
byte *body = new byte[body_size]();
int16 received_bytes = recv(tcp_socket, reinterpret_cast<char*>(body), body_size, 0);
if (received_bytes == SOCKET_ERROR || received_bytes != body_size || WSAGetLastError() != 0)
{
//there was a problem receiving the body of the message or theres no body to receive
return NetworkBuffer();
}
buffer.body = std::vector<byte>(body, body + body_size);
buffer.valid = true;
return buffer;
}
void TcpClient::send_network_message(const NetworkMessage &message, TcpClient *client)
{
NetworkBuffer buffer = NetworkMessage::EncodeMessage(message);
int32 lenght = Utility::BitConverter::ToInt32(buffer.header);
int32 bytes_sent = send(client->tcp_socket, reinterpret_cast<char*>(buffer.body.data()), lenght, 0);
if (bytes_sent == SOCKET_ERROR || bytes_sent != lenght || WSAGetLastError() != 0)
{
//something went wrong couldnt send anything/some data
}
}
void TcpClient::SendBytes(const std::vector<byte>& bytes)
{
int32 bytes_sent = send(tcp_socket, reinterpret_cast<const char*>(bytes.data()), bytes.size(), 0);
if (bytes_sent == SOCKET_ERROR || bytes_sent != bytes.size() || WSAGetLastError() != 0)
{
//something went wrong couldnt send anything/some data
}
}
void TcpClient::SendBytes(byte * bytes, uint32 size)
{
int32 bytes_sent = send(tcp_socket, reinterpret_cast<const char*>(bytes), size, 0);
if (bytes_sent == SOCKET_ERROR || bytes_sent != size || WSAGetLastError() != 0)
{
//something went wrong couldnt send anything/some data
}
}

View File

@ -1,18 +1,22 @@
#include "TcpServer.hpp"
#include "Config.hpp"
#include "Handshake.hpp"
#include "Utility.hpp"
#include <string>
#include <future>
#include <iostream>
TcpServer::TcpServer()
{
initialize(); // initialize with the default port
clients = std::vector<TcpClient>(max_connections);
}
TcpServer::TcpServer(uint16 port)
{
initialize(port);
clients = std::vector<TcpClient>(max_connections);
}
TcpServer::~TcpServer()
@ -51,7 +55,7 @@ void TcpServer::process_client_messages(TcpServer *server, TcpClient & client)
}
}
void TcpServer::SendMessage(const NetworkMessage & message)
bool TcpServer::SendMessage(const NetworkMessage & message)
{
switch (message.distribution_mode)
{
@ -65,7 +69,6 @@ void TcpServer::SendMessage(const NetworkMessage & message)
}
for (uint16 i = 0; i < OnMessageFunctions.size(); i++)
OnMessageFunctions[i](message);
break;
}
case AllAndMe: // this will send the message to EVERYONE including the user that sent it
{
@ -76,7 +79,6 @@ void TcpServer::SendMessage(const NetworkMessage & message)
}
for (uint16 i = 0; i < OnMessageFunctions.size(); i++)
OnMessageFunctions[i](message);
break;
}
case Server: // this will only send the message to the server
{
@ -84,7 +86,6 @@ void TcpServer::SendMessage(const NetworkMessage & message)
CloseSocket(message.sender);
for (uint16 i = 0; i < OnMessageFunctions.size(); i++)
OnMessageFunctions[i](message);
break;
}
case Others: // this will send the message to others, excluding server and the user that sent it
{
@ -94,7 +95,6 @@ void TcpServer::SendMessage(const NetworkMessage & message)
if (message.sender != client.GetID())
client.SendMessage(message);
}
break;
}
case ID: // this will send the message to a specific id
{
@ -102,12 +102,9 @@ void TcpServer::SendMessage(const NetworkMessage & message)
{
TcpClient client = *it;
if (message.sender == client.GetID())
{
client.SendMessage(message);
break;
}
}
break;
return false;
}
}
}
@ -190,7 +187,7 @@ const TcpClient & TcpServer::GetClientByID(uint16 id)
if (client.GetID() == id)
return client;
}
return TcpClient();
return TcpClient::DefaultTcpClient();
}
void TcpServer::SetMaxConnections(uint16 value)
@ -203,6 +200,91 @@ uint16 TcpServer::GetMaxConnections()
return max_connections;
}
#ifdef _MSC_VER
#include "TcpServerWindows.cpp"
#endif
bool TcpServer::initialize(uint16 port)
{
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
uint16 code = getaddrinfo(0, std::to_string(port).c_str(), &hints, &result);
if (code != 0)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
WSACleanup();
return false;
}
server_tcp_socket = ::socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (server_tcp_socket == INVALID_SOCKET)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
freeaddrinfo(result);
WSACleanup();
return false;
}
code = bind(server_tcp_socket, result->ai_addr, result->ai_addrlen);
if (code == SOCKET_ERROR)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
freeaddrinfo(result);
closesocket(server_tcp_socket);
WSACleanup();
return false;
}
freeaddrinfo(result);
return initialized = true;
}
bool TcpServer::StartServer(bool accept_connections)
{
if (listen(server_tcp_socket, SOMAXCONN) == SOCKET_ERROR)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl;
closesocket(server_tcp_socket);
WSACleanup();
return false;
}
if (accept_connections)
AcceptConnections();
return true;
}
void TcpServer::accept_connections(TcpServer *server)
{
while (server->running)
{
SOCKET client_socket = accept(server->server_tcp_socket, 0, 0);
if (client_socket == INVALID_SOCKET)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl;
closesocket(server->server_tcp_socket);
WSACleanup();
server->running = false; // if we cant accept a connection idk if we should stop the server or not mh
break;
}
TcpClient client(client_socket);
server->add_to_clients_list(client);
std::async(std::launch::async, &process_client_messages, server, client);
}
}
void TcpServer::shutdown_internal()
{
freeaddrinfo(result);
WSACleanup();
Utility::Delete(result);
}

View File

@ -1,96 +0,0 @@
#include "TcpServer.hpp"
#include "Config.hpp"
#include "Utility.hpp"
#include <string>
#include <iostream>
#include <future>
bool TcpServer::initialize(uint16 port)
{
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
uint16 code = getaddrinfo(0, std::to_string(port).c_str(), &hints, &result);
if (code != 0)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
WSACleanup();
return false;
}
server_tcp_socket = ::socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (server_tcp_socket == INVALID_SOCKET)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
freeaddrinfo(result);
WSACleanup();
return false;
}
code = bind(server_tcp_socket, result->ai_addr, result->ai_addrlen);
if (code == SOCKET_ERROR)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
freeaddrinfo(result);
closesocket(server_tcp_socket);
WSACleanup();
return false;
}
freeaddrinfo(result);
return initialized = true;
}
bool TcpServer::StartServer(bool accept_connections)
{
if (listen(server_tcp_socket, SOMAXCONN) == SOCKET_ERROR)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl;
closesocket(server_tcp_socket);
WSACleanup();
return false;
}
if (accept_connections)
AcceptConnections();
return true;
}
void TcpServer::accept_connections(TcpServer *server)
{
while (server->running)
{
SOCKET client_socket = accept(server->server_tcp_socket, 0, 0);
if (client_socket == INVALID_SOCKET)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl;
closesocket(server->server_tcp_socket);
WSACleanup();
server->running = false; // if we cant accept a connection idk if we should stop the server or not mh
break;
}
TcpClient client(client_socket);
server->add_to_clients_list(client);
std::async(std::launch::async, &process_client_messages, server, client);
}
}
void TcpServer::shutdown_internal()
{
freeaddrinfo(result);
WSACleanup();
Utility::Delete(result);
}

View File

@ -1,5 +1,105 @@
#include "UdpClient.hpp"
#include "Handshake.hpp"
#include "Config.hpp"
#ifdef _MSC_VER
#include "UdpClientWindows.cpp"
#endif
#include <iostream>
#include <future>
UdpClient::UdpClient(const std::string & ip)
{
initialize(ip);
}
UdpClient::UdpClient(const std::string & ip, uint16)
{
initialize(ip, port);
}
uint16 UdpClient::GetPort()
{
return port;
}
void UdpClient::SetPort(uint16 port)
{
this->port = port;
}
uint16 UdpClient::GetID()
{
return id;
}
void UdpClient::SetID(uint16 id)
{
this->id = id;
}
std::future<bool> UdpClient::SendMessage(const NetworkMessage & message)
{
return std::async(std::launch::async, &send_network_message, message, this);
}
const std::string &UdpClient::GetIP()
{
return ip;
}
void UdpClient::SetIP(const std::string & ip)
{
this->ip = ip;
}
UdpClient::UdpClient(const SOCKET & socket)
{
udp_socket = socket;
}
bool UdpClient::initialize(const std::string &ip, uint16 port)
{
if (Utility::IPUtil::ValidIPV4(ip) || port == 0)
return false;
udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (udp_socket == INVALID_SOCKET)
{
WSACleanup();
return false;
}
}
UdpClient::~UdpClient()
{
WSACleanup();
}
void UdpClient::Shutdown()
{
Handshake handshake(id, Close, Server);
SendMessage(Handshake::HandshakeToNetworkMessage(handshake));
uint16 code = closesocket(udp_socket);
if (code == SOCKET_ERROR)
{
if (Config::GetUsingConsole())
std::cerr << WSAGetLastError() << std::endl; // display more info
}
WSACleanup();
}
bool UdpClient::SendBytes(const std::vector<byte> &bytes)
{
}
bool UdpClient::SendBytes(byte *bytes, uint32 lenght)
{
}
bool UdpClient::send_network_message(const NetworkMessage &message, UdpClient *client)
{
}

View File

@ -1 +0,0 @@
#include "UdpClient.hpp"

57
src/UdpServer.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "UdpServer.hpp"
#include "Utility.hpp"
uint16 UdpServer::allocate_id()
{
for (uint16 i = 1; i < max_connections; ++i)
{
bool flag = true;
for (std::vector<UdpClient>::iterator it = clients.begin(); it != clients.end(); ++it)
{
UdpClient client = *it;
if (client.GetID() == i)
{
flag = false;
break;
}
}
if (flag)
return i;
}
return 0;
}
bool UdpServer::initialize(uint16 port)
{
server_udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (server_udp_socket == INVALID_SOCKET)
{
WSACleanup();
return false;
}
memset(&server, '\0', sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.S_un.S_un_b.s_b1 = 0;
server.sin_addr.S_un.S_un_b.s_b2 = 0;
server.sin_addr.S_un.S_un_b.s_b3 = 0;
server.sin_addr.S_un.S_un_b.s_b4 = 0;
if (bind(server_udp_socket, reinterpret_cast<struct sockaddr*>(&server), sizeof(struct sockaddr_in)) == -1)
{
closesocket(server_udp_socket);
WSACleanup();
return false;
}
return initialized = true;
}
void UdpServer::shutdown_internal()
{
WSACleanup();
}

View File

@ -162,6 +162,46 @@ const std::string & Utility::StringConverter::ToString(const std::vector<byte>&
return std::string();
}
uint8 Utility::StringConverter::ToUint8(const std::string & str)
{
return uint8();
}
uint16 Utility::StringConverter::ToUint16(const std::string & str)
{
return uint16();
}
uint32 Utility::StringConverter::ToUint32(const std::string & str)
{
return uint32();
}
uint64 Utility::StringConverter::ToUint64(const std::string & str)
{
return uint64();
}
int8 Utility::StringConverter::ToInt8(const std::string & str)
{
return int8();
}
int16 Utility::StringConverter::ToInt16(const std::string & str)
{
return int16();
}
int32 Utility::StringConverter::ToInt32(const std::string & str)
{
return int32();
}
int64 Utility::StringConverter::ToInt64(const std::string & str)
{
return int64();
}
const std::vector<byte>& Utility::StringConverter::ToBytes(const std::string & str)
{
return std::vector<byte>();
@ -224,3 +264,17 @@ const std::string & Utility::ConfigReader::operator[](const std::string &key)
{
return nodes.at(key);
}
bool Utility::IPUtil::ValidIPV4(const std::string & ip)
{
std::vector<std::string> splitted_address = Utility::StringConverter::Split(ip, ".");
if (splitted_address.size() != 4)
return false;
uint8 a1 = Utility::StringConverter::ToUint8(splitted_address[0]);
uint8 a2 = Utility::StringConverter::ToUint8(splitted_address[1]);
uint8 a3 = Utility::StringConverter::ToUint8(splitted_address[2]);
uint8 a4 = Utility::StringConverter::ToUint8(splitted_address[3]);
return a1 != 0 && a2 != 0 && a3 != 0 && a4 != 0 &&
a1 != 255 && a2 != 255 && a3 != 255 && a4 != 255;
}

View File

@ -36,8 +36,6 @@ void VoidNetClientAPI::SendMessageToAllAndMe(byte tag, byte subject, void *data)
}
void VoidNetClientAPI::SendMessage(byte distribution_mode, uint16 destination_id, byte tag, byte subject, void *data)
{
if (tag != ConnectTag && tag != DisconnectTag)
{
NetworkMessage message;
message.tag = tag;
@ -46,9 +44,9 @@ void VoidNetClientAPI::SendMessage(byte distribution_mode, uint16 destination_id
message.distribution_mode = distribution_mode;
message.sender = id;
message.destination_id = destination_id;
if (!IS_HANDSHAKE(message))
tcp_client.SendMessage(message);
}
}
void VoidNetClientAPI::Receive()
{