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:
@ -3,7 +3,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
#include "UdpClient.hpp"
|
||||
57
src/UdpServer.cpp
Normal file
57
src/UdpServer.cpp
Normal 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();
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
Reference in New Issue
Block a user