23#include <boost/asio/ip/tcp.hpp>
29#define READ_BLOCK_SIZE 4096
30#ifdef BOOST_ASIO_HAS_IOCP
31#define TC_SOCKET_USE_IOCP
61template<
class T,
class Stream = boost::asio::ip::tcp::socket>
62class Socket :
public std::enable_shared_from_this<T>
65 template<
typename... Args>
66 explicit Socket(boost::asio::ip::tcp::socket&& socket, Args&&... args) :
_socket(
std::move(socket),
std::forward<Args>(args)...),
81 boost::system::error_code error;
92#ifndef TC_SOCKET_USE_IOCP
121 [self = this->shared_from_this()](boost::system::error_code
const& error,
size_t transferredBytes)
123 self->ReadHandlerInternal(error, transferredBytes);
135 [self = this->shared_from_this(), callback](boost::system::error_code
const& error,
size_t transferredBytes)
137 (self.get()->*callback)(error, transferredBytes);
145#ifdef TC_SOCKET_USE_IOCP
157 boost::system::error_code shutdownError;
158 _socket.shutdown(boost::asio::socket_base::shutdown_send, shutdownError);
161 shutdownError.value(), shutdownError.message());
190#ifdef TC_SOCKET_USE_IOCP
193 [self = this->shared_from_this()](boost::system::error_code
const& error, std::size_t transferedBytes)
195 self->WriteHandler(error, transferedBytes);
198 _socket.async_write_some(boost::asio::null_buffers(),
199 [self = this->shared_from_this()](boost::system::error_code
const& error, std::size_t transferedBytes)
201 self->WriteHandlerWrapper(error, transferedBytes);
210 boost::system::error_code err;
211 _socket.set_option(boost::asio::ip::tcp::no_delay(enable), err);
213 TC_LOG_DEBUG(
"network",
"Socket::SetNoDelay: failed to set_option(boost::asio::ip::tcp::no_delay) for {} - {} ({})",
235#ifdef TC_SOCKET_USE_IOCP
237 void WriteHandler(boost::system::error_code
const& error, std::size_t transferedBytes)
242 _writeQueue.front().ReadCompleted(transferedBytes);
272 boost::system::error_code error;
273 std::size_t bytesSent =
_socket.write_some(boost::asio::buffer(queuedMessage.
GetReadPointer(), bytesToSend), error);
277 if (error == boost::asio::error::would_block || error == boost::asio::error::try_again)
285 else if (bytesSent == 0)
292 else if (bytesSent < bytesToSend)
#define TC_LOG_DEBUG(filterType__, message__,...)
void Resize(size_type bytes)
size_type GetRemainingSpace() const
void ReadCompleted(size_type bytes)
void WriteCompleted(size_type bytes)
size_type GetActiveSize() const
uint8 * GetWritePointer()
MessageBuffer & GetReadBuffer()
void WriteHandlerWrapper(boost::system::error_code const &, std::size_t)
Socket & operator=(Socket &&other)=delete
std::atomic< bool > _closing
MessageBuffer _readBuffer
Socket & operator=(Socket const &other)=delete
Socket(boost::asio::ip::tcp::socket &&socket, Args &&... args)
void AsyncReadWithCallback(void(T::*callback)(boost::system::error_code const &, std::size_t))
boost::asio::ip::address _remoteAddress
void DelayedCloseSocket()
Marks the socket for closing after write buffer becomes empty.
Socket(Socket &&other)=delete
boost::asio::ip::address GetRemoteIpAddress() const
void QueuePacket(MessageBuffer &&buffer)
void SetNoDelay(bool enable)
Stream & underlying_stream()
uint16 GetRemotePort() const
void ReadHandlerInternal(boost::system::error_code const &error, size_t transferredBytes)
std::queue< MessageBuffer > _writeQueue
Socket(Socket const &other)=delete
virtual void ReadHandler()=0
std::atomic< bool > _closed