Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include "Constants.h"
- #include "locked_queue.h"
- #include <boost/array.hpp>
- #include <boost/asio.hpp>
- #include <boost/bimap.hpp>
- #include <boost/thread.hpp>
- #include <string>
- #include <array>
- using boost::asio::ip::udp;
- typedef boost::bimap<__int64, udp::endpoint> ClientList;
- typedef ClientList::value_type Client;
- typedef std::pair<std::string, __int64> ClientMessage;
- class NetworkServer {
- public:
- NetworkServer(unsigned short local_port);
- ~NetworkServer();
- bool HasMessages();
- ClientMessage PopMessage();
- void SendToClient(std::string message, unsigned __int64 clientID, bool guaranteed = false);
- void SendToAllExcept(std::string message, unsigned __int64 clientID, bool guaranteed = false);
- void SendToAll(std::string message, bool guaranteed = false);
- inline unsigned __int64 GetStatReceivedMessages() {return receivedMessages;};
- inline unsigned __int64 GetStatReceivedBytes() {return receivedBytes;};
- inline unsigned __int64 GetStatSentMessages() {return sentMessages;};
- inline unsigned __int64 GetStatSentBytes() {return sentBytes;};
- private:
- // Network send/receive stuff
- boost::asio::io_service io_service;
- udp::socket socket;
- udp::endpoint server_endpoint;
- udp::endpoint remote_endpoint;
- std::array<char, NetworkBufferSize> recv_buffer;
- boost::thread service_thread;
- void start_receive();
- void handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred);
- void handle_send(std::string /*message*/, const boost::system::error_code& /*error*/, std::size_t /*bytes_transferred*/) {}
- void run_service();
- unsigned __int64 get_client_id(udp::endpoint endpoint);
- void send(std::string pmessage, udp::endpoint target_endpoint);
- // Incoming messages queue
- locked_queue<ClientMessage> incomingMessages;
- // Clients of the server
- ClientList clients;
- unsigned __int64 nextClientID;
- NetworkServer(NetworkServer&); // block default copy constructor
- // Statistics
- unsigned __int64 receivedMessages;
- unsigned __int64 receivedBytes;
- unsigned __int64 sentMessages;
- unsigned __int64 sentBytes;
- };
- #define _WIN32_WINNT 0x0501
- #include <boost/bind.hpp>
- #include "NetworkServer.h"
- #include "Logging.h"
- NetworkServer::NetworkServer(unsigned short local_port) :
- socket(io_service, udp::endpoint(udp::v4(), local_port)),
- nextClientID(0L),
- service_thread(std::bind(&NetworkServer::run_service, this))
- {
- LogMessage("Starting server on port", local_port);
- };
- NetworkServer::~NetworkServer()
- {
- io_service.stop();
- service_thread.join();
- }
- void NetworkServer::start_receive()
- {
- socket.async_receive_from(boost::asio::buffer(recv_buffer), remote_endpoint,
- boost::bind(&NetworkServer::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
- }
- void NetworkServer::handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred)
- {
- if (!error)
- {
- try {
- auto message = ClientMessage(std::string(recv_buffer.data(), recv_buffer.data() + bytes_transferred), get_client_id(remote_endpoint));
- if (!message.first.empty())
- incomingMessages.push(message);
- receivedBytes += bytes_transferred;
- receivedMessages++;
- }
- catch (std::exception ex) {
- LogMessage("handle_receive: Error parsing incoming message:",ex.what());
- }
- catch (...) {
- LogMessage("handle_receive: Unknown error while parsing incoming message");
- }
- }
- else
- {
- LogMessage("handle_receive: error: ", error.message());
- }
- start_receive();
- }
- void NetworkServer::send(std::string message, udp::endpoint target_endpoint)
- {
- socket.send_to(boost::asio::buffer(message), target_endpoint);
- sentBytes += message.size();
- sentMessages++;
- }
- void NetworkServer::run_service()
- {
- start_receive();
- while (!io_service.stopped()){
- try {
- io_service.run();
- } catch( const std::exception& e ) {
- LogMessage("Server network exception: ",e.what());
- }
- catch(...) {
- LogMessage("Unknown exception in server network thread");
- }
- }
- LogMessage("Server network thread stopped");
- };
- unsigned __int64 NetworkServer::get_client_id(udp::endpoint endpoint)
- {
- auto cit = clients.right.find(endpoint);
- if (cit != clients.right.end())
- return (*cit).second;
- nextClientID++;
- clients.insert(Client(nextClientID, endpoint));
- return nextClientID;
- };
- void NetworkServer::SendToClient(std::string message, unsigned __int64 clientID, bool guaranteed)
- {
- try {
- send(message, clients.left.at(clientID));
- }
- catch (std::out_of_range) {
- LogMessage("Unknown client ID");
- }
- };
- void NetworkServer::SendToAllExcept(std::string message, unsigned __int64 clientID, bool guaranteed)
- {
- for (auto client: clients)
- if (client.left != clientID)
- send(message, client.right);
- };
- void NetworkServer::SendToAll(std::string message, bool guaranteed)
- {
- for (auto client: clients)
- send(message, client.right);
- };
- ClientMessage NetworkServer::PopMessage() {
- return incomingMessages.pop();
- }
- bool NetworkServer::HasMessages()
- {
- return !incomingMessages.empty();
- };
- #pragma once
- #include "locked_queue.h"
- #include <boost/array.hpp>
- #include <boost/asio.hpp>
- #include <boost/thread.hpp>
- #include <memory>
- #include <array>
- #include "Constants.h"
- using boost::asio::ip::udp;
- class NetworkClient {
- public:
- NetworkClient(std::string host, std::string server_port, unsigned short local_port = 0);
- ~NetworkClient();
- void Send(std::string message);
- inline bool HasMessages() {return !incomingMessages.empty();};
- inline std::string PopMessage() { if (incomingMessages.empty()) throw std::logic_error("No messages to pop"); return incomingMessages.pop(); };
- inline unsigned __int32 GetStatReceivedMessages(){return receivedMessages;};
- inline unsigned __int64 GetStatReceivedBytes(){return receivedBytes;};
- inline unsigned __int32 GetStatSentMessages(){return sentMessages;};
- inline unsigned __int64 GetStatSentBytes(){return sentBytes;};
- private:
- // Network send/receive stuff
- boost::asio::io_service io_service;
- udp::socket socket;
- udp::endpoint server_endpoint;
- udp::endpoint remote_endpoint;
- std::array<char, NetworkBufferSize> recv_buffer;
- boost::thread service_thread;
- // Queues for messages
- locked_queue<std::string> incomingMessages;
- void start_receive();
- void handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred);
- void run_service();
- NetworkClient(NetworkClient&); // block default copy constructor
- // Statistics
- unsigned __int32 receivedMessages;
- unsigned __int64 receivedBytes;
- unsigned __int32 sentMessages;
- unsigned __int64 sentBytes;
- };
- #define _WIN32_WINNT 0x0501
- #include <boost/bind.hpp>
- #include <boost/thread.hpp>
- #include "NetworkClient.h"
- #include "Logging.h"
- NetworkClient::NetworkClient(std::string host, std::string server_port, unsigned short local_port) :
- socket(io_service, udp::endpoint(udp::v4(), local_port)),
- service_thread(std::bind(&NetworkClient::run_service, this))
- {
- receivedBytes = sentBytes = receivedMessages = sentMessages = 0;
- udp::resolver resolver(io_service);
- udp::resolver::query query(udp::v4(), host, server_port);
- server_endpoint = *resolver.resolve(query);
- Send("");
- }
- NetworkClient::~NetworkClient()
- {
- io_service.stop();
- service_thread.join();
- }
- void NetworkClient::start_receive()
- {
- socket.async_receive_from(boost::asio::buffer(recv_buffer), remote_endpoint,
- boost::bind(&NetworkClient::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
- );
- }
- void NetworkClient::handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred)
- {
- if (!error)
- {
- std::string message(recv_buffer.data(), recv_buffer.data() + bytes_transferred);
- incomingMessages.push(message);
- receivedBytes += bytes_transferred;
- receivedMessages++;
- }
- else
- {
- LogMessage("NetworkClient::handle_receive:",error);
- }
- start_receive();
- }
- void NetworkClient::Send(std::string message)
- {
- socket.send_to(boost::asio::buffer(message), server_endpoint);
- sentBytes += message.size();
- sentMessages++;
- }
- void NetworkClient::run_service()
- {
- LogMessage("Client network thread startedn");
- start_receive();
- LogMessage("Client started receivingn");
- while (!io_service.stopped()) {
- try {
- io_service.run();
- }
- catch (const std::exception& e) {
- LogMessage("Client network exception: ", e.what());
- }
- catch (...) {
- LogMessage("Unknown exception in client network thread");
- }
- }
- LogMessage("Client network thread stopped");
- }
- #pragma once
- #include <boost/thread/mutex.hpp>
- #include <queue>
- #include <list>
- template<typename _T> class locked_queue
- {
- private:
- boost::mutex mutex;
- std::queue<_T> queue;
- public:
- void push(_T value)
- {
- boost::mutex::scoped_lock lock(mutex);
- queue.push(value);
- };
- _T pop()
- {
- boost::mutex::scoped_lock lock(mutex);
- _T value;
- std::swap(value,queue.front());
- queue.pop();
- return value;
- };
- bool empty() {
- boost::mutex::scoped_lock lock(mutex);
- return queue.empty();
- }
- };
- queue.pop();
- return value;
- void NetworkServer::SendToAll(std::string message, bool guaranteed)
- {
- for (auto client: clients)
- send(message, client.right);
- };
- enum { ATTEMPT, GUARANTEE };
- SendToAll("whatever", ATTEMPT);
- enum class delivery { ATTEMPT, GUARANTEE };
- SendToAll("whatever", delivery::ATTEMPT);
- receivedBytes = sentBytes = receivedMessages = sentMessages = 0;
- NetworkClient::NetworkClient(std::string host, std::string server_port, unsigned short local_port) :
- socket(io_service, udp::endpoint(udp::v4(), local_port)),
- service_thread(std::bind(&NetworkClient::run_service, this)),
- receivedBytes(0),
- sentBytes(0),
- receivedMessages(0),
- sentMessages(0)
- {
- udp::resolver resolver(io_service);
- udp::resolver::query query(udp::v4(), host, server_port);
- server_endpoint = *resolver.resolve(query);
- Send("");
- }
- class counter {
- size_t count;
- public:
- counter &operator=(size_t val) { count = val; return *this; }
- counter(size_t count=0) : count(count) {}
- operator size_t() { return count; }
- count &operator++() { ++count; return *this; }
- count operator++(int) { counter ret(count); ++count; return ret; }
- bool operator==(counter const &other) { return count == other.count; }
- bool operator!=(counter const &other) { return count != other.count; }
- };
- #ifdef _MSC_VER
- typedef unsigned __int64 ulonglong;
- #else
- typedef unsigned long long ulonglong;
- #endif
- inline unsigned __int32 GetStatReceivedMessages(){return receivedMessages;};
- inline unsigned __int64 GetStatReceivedBytes(){return receivedBytes;};
- inline unsigned __int32 GetStatSentMessages(){return sentMessages;};
- inline unsigned __int64 GetStatSentBytes(){return sentBytes;};
- inline unsigned __int32 GetStatReceivedMessages() const {return receivedMessages;};
- inline unsigned __int64 GetStatReceivedBytes() const {return receivedBytes;};
- inline unsigned __int32 GetStatSentMessages() const {return sentMessages;};
- inline unsigned __int64 GetStatSentBytes() const {return sentBytes;};
- class stats {
- inline unsigned GetReceivedMessages() const { return receivedMessages; }
- // ...
- };
- class NetworkClient {
- stats s;
- public:
- stats Stats() const { return s; }
- };
- // ... and in client code, something like:
- NetworkClient c;
- std::cout << c.Stats().GetReceivedMessages();
- std::cout << c.Stats();
- inline unsigned __int32 GetStatReceivedMessages() const {return receivedMessages;};
- inline unsigned __int32 GetStatReceivedMessages() const { return receivedMessages; }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement