adding client/server prototype

This commit is contained in:
2022-04-23 04:53:18 +02:00
parent 06ec89b00e
commit b7541420f1
7 changed files with 248 additions and 54 deletions

View File

@@ -6,7 +6,7 @@ set(CMAKE_BUILD_TYPE Release)
project("commons" CXX) project("commons" CXX)
add_definitions("-std=c++2a -g") add_definitions("-lpthread -std=c++2a -g")
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup() conan_basic_setup()
@@ -14,6 +14,8 @@ conan_basic_setup()
add_library(commons_lib add_library(commons_lib
include/commons.cpp include/commons.cpp
src/protocol.cpp src/protocol.cpp
src/server.cpp
src/client.cpp
) )
target_include_directories (commons_lib target_include_directories (commons_lib
@@ -29,6 +31,10 @@ target_link_libraries(commons_lib
add_executable(commons add_executable(commons
src/main.cpp src/main.cpp
include/commons.cpp
src/protocol.cpp
src/server.cpp
src/client.cpp
) )
target_include_directories(commons target_include_directories(commons

29
include/client.hpp Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <boost/asio.hpp>
#include "boost/bind.hpp"
#include <functional>
#include <sstream>
#include <string>
#include <vector>
class client
{
public:
client(boost::asio::io_service& io_service,
const boost::asio::ip::address& multicast_address,
short multicast_port,
unsigned short tcp_port);
void init();
void set_outbound_interface(const boost::asio::ip::address_v4& address);
void handle_send_to(const boost::system::error_code& error);
void handle_timeout(const boost::system::error_code& error);
private:
boost::asio::ip::udp::endpoint endpoint_;
boost::asio::ip::udp::socket socket_;
boost::asio::deadline_timer timer_;
std::string message_;
unsigned short port_;
};

View File

@@ -91,12 +91,12 @@ struct composed_message : public generic_message<Type::COMPOSED_MESSAGE>
struct vec2 struct vec2
{ {
float x,y; int x,y;
}; };
struct vec3 struct vec3
{ {
float x,y,z; int x,y,z;
}; };
struct draw_rectangle : public generic_message<Type::DRAW_RECTANGLE> struct draw_rectangle : public generic_message<Type::DRAW_RECTANGLE>
@@ -126,42 +126,42 @@ struct draw_pixel : public generic_message<Type::DRAW_PIXEL>
vec3 color; vec3 color;
}; };
uint32_t get_size(Type type) //uint32_t get_size(Type type)
{ //{
static std::map<Type, uint32_t> type_map{}; // static std::map<Type, uint32_t> type_map{};
//
//initalizes map on first run // //initalizes map on first run
static bool run_once = [&](){ // static bool run_once = [&](){
type_map.emplace(Type::DRAW_PIXEL, sizeof(draw_pixel)); // type_map.emplace(Type::DRAW_PIXEL, sizeof(draw_pixel));
type_map.emplace(Type::DRAW_RECTANGLE, sizeof(draw_rectangle)); // type_map.emplace(Type::DRAW_RECTANGLE, sizeof(draw_rectangle));
type_map.emplace(Type::COMPOSED_MESSAGE, sizeof(composed_message)); // type_map.emplace(Type::COMPOSED_MESSAGE, sizeof(composed_message));
return true; // return true;
}(); // }();
//
return type_map[type]; // return type_map[type];
} //}
generic_message_base* get_object(Type type, generic_message_base* msg) //generic_message_base* get_object(Type type, generic_message_base* msg)
{ //{
switch(type) // switch(type)
{ // {
case Type::COMPOSED_MESSAGE: // case Type::COMPOSED_MESSAGE:
{ // {
return reinterpret_cast<composed_message*>(msg); // return reinterpret_cast<composed_message*>(msg);
} // }
case Type::DRAW_RECTANGLE: // case Type::DRAW_RECTANGLE:
{ // {
return reinterpret_cast<draw_rectangle*>(msg); // return reinterpret_cast<draw_rectangle*>(msg);
} // }
case Type::DRAW_PIXEL: // case Type::DRAW_PIXEL:
{ // {
return reinterpret_cast<draw_pixel*>(msg); // return reinterpret_cast<draw_pixel*>(msg);
} // }
default: // default:
return nullptr; // return nullptr;
} // }
} //}
//template<Type T> //template<Type T>
//auto* get_object(generic_message_base* msg) //auto* get_object(generic_message_base* msg)

65
include/server.hpp Normal file
View File

@@ -0,0 +1,65 @@
#pragma once
#include <cstdlib>
#include <iostream>
#include <boost/asio.hpp>
#include "protocol.hpp"
using boost::asio::ip::udp;
class server
{
public:
server(boost::asio::io_context& io_context, short port)
: socket_(io_context, udp::endpoint(udp::v4(), port))
{
do_receive();
}
void do_receive()
{
std::cout << "do_receive\n";
socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_,
[this](boost::system::error_code ec, std::size_t bytes_recvd)
{
if (!ec && bytes_recvd > 0)
{
std::cout << data_ << std::endl;
auto* msg_obj = reinterpret_cast<commons::protocol::generic_message_base*>(data_);
std::cout << "Received Type: " << static_cast<int>(msg_obj->get_type()) << "\n";
std::cout << "Received Size: " << msg_obj->get_size() << "\n";
auto* casted_obj = reinterpret_cast<commons::protocol::draw_rectangle*>(msg_obj);
std::cout << "Positon: X = " << casted_obj->position.x
<< " Y = " << casted_obj->position.y << std::endl;
do_send(bytes_recvd);
}
else
{
do_receive();
}
});
}
void do_send(std::size_t length)
{
socket_.async_send_to(
boost::asio::buffer(data_, length), sender_endpoint_,
[this](boost::system::error_code /*ec*/, std::size_t /*bytes_sent*/)
{
do_receive();
});
}
private:
udp::socket socket_;
udp::endpoint sender_endpoint_;
enum { max_length = 1024 };
char data_[max_length];
};

65
src/client.cpp Normal file
View File

@@ -0,0 +1,65 @@
#include "client.hpp"
#include "protocol.hpp"
#include <iostream>
client::client(boost::asio::io_service& io_service,
const boost::asio::ip::address& multicast_address,
short multicast_port,
unsigned short tcp_port)
: endpoint_(multicast_address, multicast_port)
, socket_(io_service, endpoint_.protocol())
, timer_(io_service)
, port_(tcp_port)
{}
void client::init()
{
std::cout << "Send test msg\n";
auto msg = std::make_unique<commons::protocol::draw_rectangle>();
msg->position = commons::protocol::vec2{3, 2};
void* void_ptr = reinterpret_cast<void*>(msg.get());
auto size = sizeof(*msg.get());
std::cout << "Object Type: " << static_cast<int>(msg->get_type()) << "\n";
std::cout << "Object size: " << size << "\n";
std::cout << "Positon: X = " << msg->position.x
<< " Y = " << msg->position.y << std::endl;
socket_.async_send_to(
boost::asio::buffer(void_ptr, size), endpoint_,
std::bind(&client::handle_send_to, this,
std::placeholders::_1));
}
void client::set_outbound_interface(const boost::asio::ip::address_v4& address)
{
boost::asio::ip::multicast::outbound_interface option(address);
socket_.set_option(option);
}
void client::handle_send_to(const boost::system::error_code& error)
{
if(!error)
{
timer_.expires_from_now(boost::posix_time::seconds(1));
timer_.async_wait( std::bind(&client::handle_timeout, this,
std::placeholders::_1));
}
}
void client::handle_timeout(const boost::system::error_code& error)
{
if (!error)
{
//spdlog::trace("Resending Message: '{}'", "TestMessage");
std::cout << "done\n";
//socket_.async_send_to(
// boost::asio::buffer("TestMessage"), endpoint_,
// std::bind(&client::handle_send_to, this,
// std::placeholders::_1));
}
}

View File

@@ -1,27 +1,55 @@
#include <iostream> #include <iostream>
#include <boost/asio.hpp>
#include "protocol.hpp" #include "protocol.hpp"
#include "server.hpp"
#include "client.hpp"
int main()
int main(int argc, char* argv[])
{ {
using namespace commons::protocol; try
auto draw_msg = draw_rectangle{}; {
boost::asio::io_context io_context;
if(argc == 1)
{
std::cout << "Running client\n";
client s(io_context, boost::asio::ip::make_address("0.0.0.0"), 9000, 0);
s.init();
io_context.run();
}
for(int i = 0; i < 3; ++i) if(argc == 2)
{ {
std::cout << "Size of " << i << " is " << get_size(static_cast<Type>(i)) << "\n"; std::cout << "Running server\n";
} server s(io_context, 9000);
io_context.run();
}
auto rectangle = std::make_unique<draw_pixel>(); }
void* void_ptr = reinterpret_cast<void*>(rectangle.get()); catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
generic_message_base* rectangle_ptr = reinterpret_cast<generic_message_base*>(void_ptr); return 0;
std::cout << "Type: " << static_cast<int>(rectangle_ptr->get_type()) << "\n"; // using namespace commons::protocol;
std::cout << "Size: " << static_cast<int>(rectangle_ptr->get_size()) << "\n"; // auto draw_msg = draw_rectangle{};
//
auto* final_msg = get_object(rectangle_ptr->get_type(), rectangle_ptr); // for(int i = 0; i < 3; ++i)
// {
return 0; // std::cout << "Size of " << i << " is " << get_size(static_cast<Type>(i)) << "\n";
// }
//
// auto rectangle = std::make_unique<draw_pixel>();
// void* void_ptr = reinterpret_cast<void*>(rectangle.get());
//
// generic_message_base* rectangle_ptr = reinterpret_cast<generic_message_base*>(void_ptr);
//
// std::cout << "Type: " << static_cast<int>(rectangle_ptr->get_type()) << "\n";
// std::cout << "Size: " << static_cast<int>(rectangle_ptr->get_size()) << "\n";
//
// auto* final_msg = get_object(rectangle_ptr->get_type(), rectangle_ptr);
//
// return 0;
} }

1
src/server.cpp Normal file
View File

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