Advertisement
Guest User

Untitled

a guest
Jun 15th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.14 KB | None | 0 0
  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; }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement