diff --git a/TODO b/TODO
index d2032d8..3c5137c 100644
--- a/TODO
+++ b/TODO
@@ -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...
\ No newline at end of file
+maybe i should use virtual methods for the server and client, maybe...
+
+TcpServer::SendMessage rework
\ No newline at end of file
diff --git a/VoidNetVS/VoidNetVS/VoidNetVS.vcxproj b/VoidNetVS/VoidNetVS/VoidNetVS.vcxproj
index e4924d7..4cad46f 100644
--- a/VoidNetVS/VoidNetVS/VoidNetVS.vcxproj
+++ b/VoidNetVS/VoidNetVS/VoidNetVS.vcxproj
@@ -29,6 +29,7 @@
+
@@ -44,17 +45,9 @@
-
- true
-
-
- true
-
-
- true
-
+
diff --git a/VoidNetVS/VoidNetVS/VoidNetVS.vcxproj.filters b/VoidNetVS/VoidNetVS/VoidNetVS.vcxproj.filters
index 3d76a3a..cc7daca 100644
--- a/VoidNetVS/VoidNetVS/VoidNetVS.vcxproj.filters
+++ b/VoidNetVS/VoidNetVS/VoidNetVS.vcxproj.filters
@@ -48,14 +48,14 @@
include
+
+ include
+
src
-
- src
-
src
@@ -74,9 +74,6 @@
src
-
- src
-
src
@@ -92,7 +89,7 @@
src
-
+
src
diff --git a/include/Defs.hpp b/include/Defs.hpp
index dd405ee..ec596ab 100644
--- a/include/Defs.hpp
+++ b/include/Defs.hpp
@@ -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
\ No newline at end of file
diff --git a/include/Init.hpp b/include/Init.hpp
index 45e0bd4..af477b4 100644
--- a/include/Init.hpp
+++ b/include/Init.hpp
@@ -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
\ No newline at end of file
diff --git a/include/TcpClient.hpp b/include/TcpClient.hpp
index fc86d8b..c6d8766 100644
--- a/include/TcpClient.hpp
+++ b/include/TcpClient.hpp
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#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 &bytes);
- void SendBytes(byte *bytes, uint32 lenght);
+
+ std::future SendMessage(const NetworkMessage &message);
+ bool SendBytes(const std::vector &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 OnConnect;
std::function OnMessage;
-#ifdef _MSC_VER
SOCKET tcp_socket = INVALID_SOCKET;
struct addrinfo *result = nullptr;
struct addrinfo hints;
-#endif
};
#endif
\ No newline at end of file
diff --git a/include/TcpServer.hpp b/include/TcpServer.hpp
index f4bd958..16f877e 100644
--- a/include/TcpServer.hpp
+++ b/include/TcpServer.hpp
@@ -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 clients;
-#ifdef _MSC_VER
SOCKET server_tcp_socket = INVALID_SOCKET;
struct addrinfo *result = nullptr;
struct addrinfo hints;
-#endif
};
#endif
diff --git a/include/UdpClient.hpp b/include/UdpClient.hpp
index 1c34328..d239e57 100644
--- a/include/UdpClient.hpp
+++ b/include/UdpClient.hpp
@@ -9,11 +9,49 @@
#include "NetworkMessage.hpp"
#include
+#include
#include
+#include
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 SendMessage(const NetworkMessage &message);
+ bool SendBytes(const std::vector &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 OnDisconnect;
+ std::function OnConnect;
+ std::function OnMessage;
+
+ SOCKET udp_socket = INVALID_SOCKET;
};
#endif
diff --git a/include/UdpServer.hpp b/include/UdpServer.hpp
new file mode 100644
index 0000000..7ab44b2
--- /dev/null
+++ b/include/UdpServer.hpp
@@ -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
+#include
+
+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 clients;
+
+ SOCKET server_udp_socket = INVALID_SOCKET;
+ struct sockaddr_in server;
+};
+
+#endif
\ No newline at end of file
diff --git a/include/Utility.hpp b/include/Utility.hpp
index b4978a3..13759cd 100644
--- a/include/Utility.hpp
+++ b/include/Utility.hpp
@@ -56,6 +56,15 @@ struct Utility
static const std::string &ToString(int64 value);
static const std::string &ToString(const std::vector &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 &ToBytes(const std::string &str);
static const std::string &ToString(const std::vector &bytes, uint16 start_index = 0, uint16 lenght = 0);
@@ -64,6 +73,11 @@ struct Utility
static std::vector 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);
diff --git a/src/InitWindows.cpp b/src/InitWindows.cpp
index 8c9565a..18b8dd4 100644
--- a/src/InitWindows.cpp
+++ b/src/InitWindows.cpp
@@ -3,7 +3,7 @@
#include
-bool Initialization::initialize()
+bool Initialization::Initialize()
{
uint16 code = WSAStartup(MAKEWORD(2, 2), &wsa_data);
if (code != 0)
@@ -13,4 +13,9 @@ bool Initialization::initialize()
return false;
}
return true;
+}
+
+const WSADATA &Initialization::GetData()
+{
+ return wsa_data;
}
\ No newline at end of file
diff --git a/src/TcpClient.cpp b/src/TcpClient.cpp
index 091e7f8..b9b6b06 100644
--- a/src/TcpClient.cpp
+++ b/src/TcpClient.cpp
@@ -1,8 +1,12 @@
#include "TcpClient.hpp"
#include "NetworkBuffer.hpp"
+#include "Utility.hpp"
+#include "Config.hpp"
+#include "Handshake.hpp"
#include
#include
+#include
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 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
\ No newline at end of file
+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(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(header), sizeof(int32), 0) != sizeof(int32))
+ return NetworkBuffer();
+ buffer.header = std::vector(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(body), body_size, 0);
+ if (received_bytes == SOCKET_ERROR || received_bytes != body_size || WSAGetLastError() != 0)
+ return NetworkBuffer();
+
+ buffer.body = std::vector(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(buffer.body.data()), lenght, 0);
+ return bytes_sent == SOCKET_ERROR || bytes_sent != lenght || WSAGetLastError() != 0;
+}
+
+bool TcpClient::SendBytes(const std::vector& bytes)
+{
+ int32 bytes_sent = send(tcp_socket, reinterpret_cast(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(bytes), size, 0);
+ return bytes_sent == SOCKET_ERROR || bytes_sent != size || WSAGetLastError() != 0;
+}
\ No newline at end of file
diff --git a/src/TcpClientWindows.cpp b/src/TcpClientWindows.cpp
deleted file mode 100644
index 525d46d..0000000
--- a/src/TcpClientWindows.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "TcpClient.hpp"
-#include "Utility.hpp"
-#include "Config.hpp"
-#include "Handshake.hpp"
-
-#include
-
-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(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(header), sizeof(int32), 0) != sizeof(int32))
- //invalid header
- return NetworkBuffer();
- buffer.header = std::vector(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(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(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(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& bytes)
-{
- int32 bytes_sent = send(tcp_socket, reinterpret_cast(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(bytes), size, 0);
- if (bytes_sent == SOCKET_ERROR || bytes_sent != size || WSAGetLastError() != 0)
- {
- //something went wrong couldnt send anything/some data
- }
-}
\ No newline at end of file
diff --git a/src/TcpServer.cpp b/src/TcpServer.cpp
index 31a990b..836ce43 100644
--- a/src/TcpServer.cpp
+++ b/src/TcpServer.cpp
@@ -1,18 +1,22 @@
#include "TcpServer.hpp"
#include "Config.hpp"
#include "Handshake.hpp"
+#include "Utility.hpp"
+#include
#include
#include
TcpServer::TcpServer()
{
initialize(); // initialize with the default port
+ clients = std::vector(max_connections);
}
TcpServer::TcpServer(uint16 port)
{
initialize(port);
+ clients = std::vector(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
\ No newline at end of file
+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);
+}
\ No newline at end of file
diff --git a/src/TcpServerWindows.cpp b/src/TcpServerWindows.cpp
deleted file mode 100644
index 24fbd70..0000000
--- a/src/TcpServerWindows.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-#include "TcpServer.hpp"
-#include "Config.hpp"
-#include "Utility.hpp"
-
-#include
-#include
-#include
-
-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);
-}
\ No newline at end of file
diff --git a/src/UdpClient.cpp b/src/UdpClient.cpp
index 7b8cb80..3e4dbd9 100644
--- a/src/UdpClient.cpp
+++ b/src/UdpClient.cpp
@@ -1,5 +1,105 @@
#include "UdpClient.hpp"
+#include "Handshake.hpp"
+#include "Config.hpp"
-#ifdef _MSC_VER
-#include "UdpClientWindows.cpp"
-#endif
\ No newline at end of file
+#include
+
+#include
+
+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 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 &bytes)
+{
+
+}
+
+bool UdpClient::SendBytes(byte *bytes, uint32 lenght)
+{
+
+}
+
+bool UdpClient::send_network_message(const NetworkMessage &message, UdpClient *client)
+{
+
+}
\ No newline at end of file
diff --git a/src/UdpClientWindows.cpp b/src/UdpClientWindows.cpp
deleted file mode 100644
index 8c55758..0000000
--- a/src/UdpClientWindows.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "UdpClient.hpp"
diff --git a/src/UdpServer.cpp b/src/UdpServer.cpp
new file mode 100644
index 0000000..c513de6
--- /dev/null
+++ b/src/UdpServer.cpp
@@ -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::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(&server), sizeof(struct sockaddr_in)) == -1)
+ {
+ closesocket(server_udp_socket);
+ WSACleanup();
+ return false;
+ }
+ return initialized = true;
+}
+
+void UdpServer::shutdown_internal()
+{
+ WSACleanup();
+}
\ No newline at end of file
diff --git a/src/Utility.cpp b/src/Utility.cpp
index dd67a24..588724c 100644
--- a/src/Utility.cpp
+++ b/src/Utility.cpp
@@ -162,6 +162,46 @@ const std::string & Utility::StringConverter::ToString(const std::vector&
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& Utility::StringConverter::ToBytes(const std::string & str)
{
return std::vector();
@@ -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 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;
+}
diff --git a/src/VoidNetClient.cpp b/src/VoidNetClient.cpp
index 0357647..44f5963 100644
--- a/src/VoidNetClient.cpp
+++ b/src/VoidNetClient.cpp
@@ -37,17 +37,15 @@ 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;
- message.subject = subject;
- message.data = data;
- message.distribution_mode = distribution_mode;
- message.sender = id;
- message.destination_id = destination_id;
+ NetworkMessage message;
+ message.tag = tag;
+ message.subject = subject;
+ message.data = data;
+ message.distribution_mode = distribution_mode;
+ message.sender = id;
+ message.destination_id = destination_id;
+ if (!IS_HANDSHAKE(message))
tcp_client.SendMessage(message);
- }
}
void VoidNetClientAPI::Receive()