SHARE
TWEET

Untitled

a guest Jun 15th, 2019 50 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #pragma once
  2.  
  3. #include "Constants.h"
  4. #include "locked_queue.h"
  5.  
  6. #include <boost/array.hpp>
  7. #include <boost/asio.hpp>
  8. #include <boost/bimap.hpp>
  9. #include <boost/thread.hpp>
  10.  
  11. #include <string>
  12. #include <array>
  13.  
  14. using boost::asio::ip::udp;
  15.  
  16. typedef boost::bimap<__int64, udp::endpoint> ClientList;
  17. typedef ClientList::value_type Client;
  18. typedef std::pair<std::string, __int64> ClientMessage;
  19.  
  20. class NetworkServer {
  21. public:
  22.     NetworkServer(unsigned short local_port);
  23.     ~NetworkServer();
  24.  
  25.     bool HasMessages();
  26.     ClientMessage PopMessage();
  27.  
  28.     void SendToClient(std::string message, unsigned __int64 clientID, bool guaranteed = false);
  29.     void SendToAllExcept(std::string message, unsigned __int64 clientID, bool guaranteed = false);
  30.     void SendToAll(std::string message, bool guaranteed = false);
  31.  
  32.     inline unsigned __int64 GetStatReceivedMessages() {return receivedMessages;};
  33.     inline unsigned __int64 GetStatReceivedBytes()    {return receivedBytes;};
  34.     inline unsigned __int64 GetStatSentMessages()     {return sentMessages;};
  35.     inline unsigned __int64 GetStatSentBytes()        {return sentBytes;};
  36.  
  37. private:
  38.     // Network send/receive stuff
  39.     boost::asio::io_service io_service;
  40.     udp::socket socket;
  41.     udp::endpoint server_endpoint;
  42.     udp::endpoint remote_endpoint;
  43.     std::array<char, NetworkBufferSize> recv_buffer;
  44.     boost::thread service_thread;
  45.  
  46.     void start_receive();
  47.     void handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred);
  48.     void handle_send(std::string /*message*/, const boost::system::error_code& /*error*/, std::size_t /*bytes_transferred*/)    {}
  49.     void run_service();
  50.     unsigned __int64 get_client_id(udp::endpoint endpoint);
  51.  
  52.     void send(std::string pmessage, udp::endpoint target_endpoint);
  53.  
  54.     // Incoming messages queue
  55.     locked_queue<ClientMessage> incomingMessages;
  56.  
  57.     // Clients of the server
  58.     ClientList clients;
  59.     unsigned __int64 nextClientID;
  60.  
  61.     NetworkServer(NetworkServer&); // block default copy constructor
  62.  
  63.     // Statistics
  64.     unsigned __int64 receivedMessages;
  65.     unsigned __int64 receivedBytes;
  66.     unsigned __int64 sentMessages;
  67.     unsigned __int64 sentBytes;
  68. };
  69.      
  70. #define _WIN32_WINNT 0x0501
  71. #include <boost/bind.hpp>
  72.  
  73. #include "NetworkServer.h"
  74. #include "Logging.h"
  75.  
  76. NetworkServer::NetworkServer(unsigned short local_port) :
  77.     socket(io_service, udp::endpoint(udp::v4(), local_port)),
  78.     nextClientID(0L),
  79.     service_thread(std::bind(&NetworkServer::run_service, this))
  80. {
  81.     LogMessage("Starting server on port", local_port);
  82. };
  83.  
  84. NetworkServer::~NetworkServer()
  85. {
  86.     io_service.stop();
  87.     service_thread.join();
  88. }
  89.  
  90. void NetworkServer::start_receive()
  91. {
  92.     socket.async_receive_from(boost::asio::buffer(recv_buffer), remote_endpoint,
  93.         boost::bind(&NetworkServer::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
  94. }
  95.  
  96. void NetworkServer::handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred)
  97. {
  98.     if (!error)
  99.     {
  100.         try {
  101.             auto message = ClientMessage(std::string(recv_buffer.data(), recv_buffer.data() + bytes_transferred), get_client_id(remote_endpoint));
  102.             if (!message.first.empty())
  103.                 incomingMessages.push(message);
  104.             receivedBytes += bytes_transferred;
  105.             receivedMessages++;
  106.         }
  107.         catch (std::exception ex) {
  108.             LogMessage("handle_receive: Error parsing incoming message:",ex.what());
  109.         }
  110.         catch (...) {
  111.             LogMessage("handle_receive: Unknown error while parsing incoming message");
  112.         }
  113.     }
  114.     else
  115.     {
  116.         LogMessage("handle_receive: error: ", error.message());
  117.     }
  118.  
  119.     start_receive();
  120. }
  121.  
  122. void NetworkServer::send(std::string message, udp::endpoint target_endpoint)
  123. {
  124.     socket.send_to(boost::asio::buffer(message), target_endpoint);
  125.     sentBytes += message.size();
  126.     sentMessages++;
  127. }
  128.  
  129. void NetworkServer::run_service()
  130. {
  131.     start_receive();
  132.     while (!io_service.stopped()){
  133.         try {
  134.             io_service.run();
  135.         } catch( const std::exception& e ) {
  136.             LogMessage("Server network exception: ",e.what());
  137.         }
  138.         catch(...) {
  139.             LogMessage("Unknown exception in server network thread");
  140.         }
  141.     }
  142.     LogMessage("Server network thread stopped");
  143. };
  144.  
  145. unsigned __int64 NetworkServer::get_client_id(udp::endpoint endpoint)
  146. {
  147.     auto cit = clients.right.find(endpoint);
  148.     if (cit != clients.right.end())
  149.         return (*cit).second;
  150.  
  151.     nextClientID++;
  152.     clients.insert(Client(nextClientID, endpoint));
  153.     return nextClientID;
  154. };
  155.  
  156. void NetworkServer::SendToClient(std::string message, unsigned __int64 clientID, bool guaranteed)
  157. {
  158.     try {
  159.         send(message, clients.left.at(clientID));
  160.     }
  161.     catch (std::out_of_range) {
  162.         LogMessage("Unknown client ID");
  163.     }
  164. };
  165.  
  166. void NetworkServer::SendToAllExcept(std::string message, unsigned __int64 clientID, bool guaranteed)
  167. {
  168.     for (auto client: clients)
  169.         if (client.left != clientID)
  170.             send(message, client.right);
  171. };
  172.  
  173. void NetworkServer::SendToAll(std::string message, bool guaranteed)
  174. {
  175.     for (auto client: clients)
  176.         send(message, client.right);
  177. };
  178.  
  179. ClientMessage NetworkServer::PopMessage() {
  180.     return incomingMessages.pop();
  181. }
  182.  
  183. bool NetworkServer::HasMessages()
  184. {
  185.     return !incomingMessages.empty();
  186. };
  187.      
  188. #pragma once
  189. #include "locked_queue.h"
  190.  
  191. #include <boost/array.hpp>
  192. #include <boost/asio.hpp>
  193. #include <boost/thread.hpp>
  194.  
  195. #include <memory>
  196. #include <array>
  197.  
  198. #include "Constants.h"
  199.  
  200. using boost::asio::ip::udp;
  201.  
  202. class NetworkClient {
  203. public:
  204.     NetworkClient(std::string host, std::string server_port, unsigned short local_port = 0);
  205.     ~NetworkClient();
  206.  
  207.     void Send(std::string message);
  208.     inline bool HasMessages() {return !incomingMessages.empty();};
  209.     inline std::string PopMessage() { if (incomingMessages.empty()) throw std::logic_error("No messages to pop"); return incomingMessages.pop(); };
  210.  
  211.     inline unsigned __int32 GetStatReceivedMessages(){return receivedMessages;};
  212.     inline unsigned __int64 GetStatReceivedBytes(){return receivedBytes;};
  213.     inline unsigned __int32 GetStatSentMessages(){return sentMessages;};
  214.     inline unsigned __int64 GetStatSentBytes(){return sentBytes;};
  215. private:
  216.     // Network send/receive stuff
  217.     boost::asio::io_service io_service;
  218.     udp::socket socket;
  219.     udp::endpoint server_endpoint;
  220.     udp::endpoint remote_endpoint;
  221.     std::array<char, NetworkBufferSize> recv_buffer;
  222.     boost::thread service_thread;
  223.  
  224.     // Queues for messages
  225.     locked_queue<std::string> incomingMessages;
  226.  
  227.     void start_receive();
  228.     void handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred);
  229.     void run_service();
  230.  
  231.     NetworkClient(NetworkClient&); // block default copy constructor
  232.  
  233.     // Statistics
  234.     unsigned __int32 receivedMessages;
  235.     unsigned __int64 receivedBytes;
  236.     unsigned __int32 sentMessages;
  237.     unsigned __int64 sentBytes;
  238. };
  239.      
  240. #define _WIN32_WINNT 0x0501
  241. #include <boost/bind.hpp>
  242. #include <boost/thread.hpp>
  243.  
  244. #include "NetworkClient.h"
  245. #include "Logging.h"
  246.  
  247. NetworkClient::NetworkClient(std::string host, std::string server_port, unsigned short local_port) :
  248.     socket(io_service, udp::endpoint(udp::v4(), local_port)),
  249.     service_thread(std::bind(&NetworkClient::run_service, this))
  250. {
  251.     receivedBytes = sentBytes = receivedMessages = sentMessages = 0;
  252.  
  253.     udp::resolver resolver(io_service);
  254.     udp::resolver::query query(udp::v4(), host, server_port);
  255.     server_endpoint = *resolver.resolve(query);
  256.     Send("");
  257. }
  258.  
  259. NetworkClient::~NetworkClient()
  260. {
  261.     io_service.stop();
  262.     service_thread.join();
  263. }
  264.  
  265. void NetworkClient::start_receive()
  266. {
  267.     socket.async_receive_from(boost::asio::buffer(recv_buffer), remote_endpoint,
  268.         boost::bind(&NetworkClient::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
  269.     );
  270. }
  271.  
  272. void NetworkClient::handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred)
  273. {
  274.     if (!error)
  275.     {
  276.         std::string message(recv_buffer.data(), recv_buffer.data() + bytes_transferred);
  277.         incomingMessages.push(message);
  278.         receivedBytes += bytes_transferred;
  279.         receivedMessages++;
  280.     }
  281.     else
  282.     {
  283.         LogMessage("NetworkClient::handle_receive:",error);
  284.     }
  285.  
  286.     start_receive();
  287. }
  288.  
  289. void NetworkClient::Send(std::string message)
  290. {
  291.     socket.send_to(boost::asio::buffer(message), server_endpoint);
  292.  
  293.     sentBytes += message.size();
  294.     sentMessages++;
  295. }
  296.  
  297. void NetworkClient::run_service()
  298. {
  299.     LogMessage("Client network thread startedn");
  300.     start_receive();
  301.     LogMessage("Client started receivingn");
  302.     while (!io_service.stopped()) {
  303.         try {
  304.             io_service.run();
  305.         }
  306.         catch (const std::exception& e) {
  307.             LogMessage("Client network exception: ", e.what());
  308.         }
  309.         catch (...) {
  310.             LogMessage("Unknown exception in client network thread");
  311.         }
  312.     }
  313.     LogMessage("Client network thread stopped");
  314. }
  315.      
  316. #pragma once
  317. #include <boost/thread/mutex.hpp>
  318. #include <queue>
  319. #include <list>
  320.  
  321. template<typename _T> class locked_queue
  322. {
  323. private:
  324.     boost::mutex mutex;
  325.     std::queue<_T> queue;
  326. public:
  327.     void push(_T value)
  328.     {
  329.         boost::mutex::scoped_lock lock(mutex);
  330.         queue.push(value);
  331.     };
  332.  
  333.     _T pop()
  334.     {
  335.         boost::mutex::scoped_lock lock(mutex);
  336.         _T value;
  337.         std::swap(value,queue.front());
  338.         queue.pop();
  339.         return value;
  340.     };
  341.  
  342.     bool empty() {
  343.         boost::mutex::scoped_lock lock(mutex);
  344.         return queue.empty();
  345.     }
  346. };
  347.      
  348. queue.pop();
  349.     return value;
  350.      
  351. void NetworkServer::SendToAll(std::string message, bool guaranteed)
  352.     {
  353.         for (auto client: clients)
  354.             send(message, client.right);
  355.     };
  356.      
  357. enum { ATTEMPT, GUARANTEE };
  358.  
  359. SendToAll("whatever", ATTEMPT);
  360.      
  361. enum class delivery { ATTEMPT, GUARANTEE };
  362.  
  363. SendToAll("whatever", delivery::ATTEMPT);
  364.      
  365. receivedBytes = sentBytes = receivedMessages = sentMessages = 0;
  366.      
  367. NetworkClient::NetworkClient(std::string host, std::string server_port, unsigned short local_port) :
  368.     socket(io_service, udp::endpoint(udp::v4(), local_port)),
  369.     service_thread(std::bind(&NetworkClient::run_service, this)),
  370.     receivedBytes(0),
  371.     sentBytes(0),
  372.     receivedMessages(0),
  373.     sentMessages(0)
  374. {
  375.     udp::resolver resolver(io_service);
  376.     udp::resolver::query query(udp::v4(), host, server_port);
  377.     server_endpoint = *resolver.resolve(query);
  378.     Send("");
  379. }
  380.      
  381. class counter {
  382.     size_t count;
  383. public:
  384.     counter &operator=(size_t val) { count = val; return *this; }
  385.     counter(size_t count=0) : count(count) {}
  386.     operator size_t() { return count; }
  387.     count &operator++() { ++count; return *this; }
  388.     count operator++(int) { counter ret(count); ++count; return ret; }
  389.     bool operator==(counter const &other) { return count == other.count; }
  390.     bool operator!=(counter const &other) { return count != other.count; }
  391. };
  392.      
  393. #ifdef _MSC_VER
  394. typedef unsigned __int64 ulonglong;
  395. #else
  396. typedef unsigned long long ulonglong;
  397. #endif
  398.      
  399. inline unsigned __int32 GetStatReceivedMessages(){return receivedMessages;};
  400. inline unsigned __int64 GetStatReceivedBytes(){return receivedBytes;};
  401. inline unsigned __int32 GetStatSentMessages(){return sentMessages;};
  402. inline unsigned __int64 GetStatSentBytes(){return sentBytes;};
  403.      
  404. inline unsigned __int32 GetStatReceivedMessages() const {return receivedMessages;};
  405. inline unsigned __int64 GetStatReceivedBytes() const {return receivedBytes;};
  406. inline unsigned __int32 GetStatSentMessages() const {return sentMessages;};
  407. inline unsigned __int64 GetStatSentBytes() const {return sentBytes;};
  408.      
  409. class stats {
  410.     inline unsigned GetReceivedMessages() const { return receivedMessages; }
  411.     // ...
  412. };
  413.  
  414. class NetworkClient {
  415.     stats s;
  416. public:
  417.     stats Stats() const { return s; }
  418. };
  419.  
  420. // ... and in client code, something like:
  421. NetworkClient c;
  422.  
  423. std::cout << c.Stats().GetReceivedMessages();
  424.      
  425. std::cout << c.Stats();
  426.      
  427. inline unsigned __int32 GetStatReceivedMessages() const {return receivedMessages;};
  428.      
  429. inline unsigned __int32 GetStatReceivedMessages() const { return receivedMessages; }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top