From c1b1ba44ba306ec41a981009f37d265283618d9f Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 26 Jul 2014 23:26:01 +0200 Subject: Core/Network: Refactored socket code, moved common operations to base Socket class --- src/server/shared/Networking/Socket.h | 109 ++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/server/shared/Networking/Socket.h (limited to 'src/server/shared/Networking') diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h new file mode 100644 index 00000000000..daefa0d4ad5 --- /dev/null +++ b/src/server/shared/Networking/Socket.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef __SOCKET_H__ +#define __SOCKET_H__ + +#include "Define.h" +#include "Log.h" +#include +#include +#include +#include +#include +#include +#include + +using boost::asio::ip::tcp; + +template +class Socket : public std::enable_shared_from_this +{ +public: + Socket(tcp::socket&& socket, std::size_t headerSize) : _socket(std::move(socket)), _headerSize(headerSize) { } + + virtual void Start() = 0; + + boost::asio::ip::address GetRemoteIpAddress() const { return _socket.remote_endpoint().address(); }; + uint16 GetRemotePort() const { return _socket.remote_endpoint().port(); } + + void AsyncReadHeader() + { + _socket.async_read_some(boost::asio::buffer(_readBuffer, _headerSize), boost::bind(&Socket::ReadHeaderHandlerInternal, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + } + + void AsyncReadData(std::size_t size, std::size_t bufferOffset) + { + _socket.async_read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size), boost::bind(&Socket::ReadDataHandlerInternal, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + } + + void ReadData(std::size_t size, std::size_t bufferOffset) + { + _socket.read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size)); + } + + void AsyncWrite(std::vector const& data) + { + boost::asio::async_write(_socket, boost::asio::buffer(data), boost::bind(&Socket::WriteHandler, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + } + + bool IsOpen() const { return _socket.is_open(); } + void CloseSocket() + { + boost::system::error_code socketError; + _socket.close(socketError); + if (socketError) + TC_LOG_DEBUG("network", "Socket::CloseSocket: %s errored when closing socket: %i (%s)", GetRemoteIpAddress().to_string().c_str(), socketError.value(), socketError.message().c_str()); + } + + uint8* GetReadBuffer() { return _readBuffer; } + +protected: + virtual void ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) = 0; + virtual void ReadDataHandler(boost::system::error_code error, size_t transferedBytes) = 0; + + std::mutex _writeLock; + std::queue > _writeQueue; + +private: + void ReadHeaderHandlerInternal(boost::system::error_code error, size_t transferedBytes) { ReadHeaderHandler(error, transferedBytes); } + void ReadDataHandlerInternal(boost::system::error_code error, size_t transferedBytes) { ReadDataHandler(error, transferedBytes); } + + void WriteHandler(boost::system::error_code error, size_t /*transferedBytes*/) + { + if (!error) + { + std::lock_guard deleteGuard(_writeLock); + + _writeQueue.pop(); + + if (!_writeQueue.empty()) + AsyncWrite(_writeQueue.front()); + } + else + CloseSocket(); + } + + tcp::socket _socket; + + uint8 _readBuffer[4096]; + + std::size_t _headerSize; +}; + +#endif // __SOCKET_H__ -- cgit v1.2.3