diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d847d10..1d9feb91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,7 @@ SET(SOURCES src/framework/net/outputmessage.cpp src/framework/net/protocol.cpp src/framework/net/rsa.cpp + src/framework/net/server.cpp # framework util src/framework/util/translator.cpp diff --git a/src/framework/net/connection.cpp b/src/framework/net/connection.cpp index 06e1d432..9f4f672c 100644 --- a/src/framework/net/connection.cpp +++ b/src/framework/net/connection.cpp @@ -105,11 +105,26 @@ void Connection::read(uint16 bytes, const RecvCallback& callback) return; m_recvCallback = callback; - m_recvSize = bytes; asio::async_read(m_socket, asio::buffer(m_recvBuffer, bytes), - std::bind(&Connection::onRecv, shared_from_this(), _1)); + std::bind(&Connection::onRecv, shared_from_this(), _1, bytes)); + + m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT)); + m_readTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), _1)); +} + +void Connection::read_some(const RecvCallback& callback) +{ + m_readTimer.cancel(); + + if(!m_connected) + return; + + m_recvCallback = callback; + + m_socket.async_read_some(asio::buffer(m_recvBuffer, RECV_BUFFER_SIZE), + std::bind(&Connection::onRecv, shared_from_this(), _1, _2)); m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT)); m_readTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), _1)); @@ -138,7 +153,7 @@ void Connection::onConnect(const boost::system::error_code& error) g_dispatcher.addEvent(m_connectCallback); } else handleError(error); - + m_connecting = false; } @@ -153,7 +168,7 @@ void Connection::onWrite(const boost::system::error_code& error, size_t) handleError(error); } -void Connection::onRecv(const boost::system::error_code& error) +void Connection::onRecv(const boost::system::error_code& error, size_t recvSize) { m_readTimer.cancel(); @@ -162,7 +177,7 @@ void Connection::onRecv(const boost::system::error_code& error) if(!error) { if(m_recvCallback) - g_dispatcher.addEvent(std::bind(m_recvCallback, m_recvBuffer, m_recvSize)); + g_dispatcher.addEvent(std::bind(m_recvCallback, m_recvBuffer, recvSize)); } else handleError(error); } diff --git a/src/framework/net/connection.h b/src/framework/net/connection.h index bd962d3d..b1a40f8b 100644 --- a/src/framework/net/connection.h +++ b/src/framework/net/connection.h @@ -32,8 +32,9 @@ class Connection : public std::enable_shared_from_this, boost::nonco typedef std::function RecvCallback; enum { - READ_TIMEOUT = 10, - WRITE_TIMEOUT = 10 + READ_TIMEOUT = 30, + WRITE_TIMEOUT = 30, + RECV_BUFFER_SIZE = 65536 }; public: @@ -48,17 +49,18 @@ public: void write(uint8* buffer, uint16 size); void read(uint16 bytes, const RecvCallback& callback); + void read_some(const RecvCallback& callback); void setErrorCallback(const ErrorCallback& errorCallback) { m_errorCallback = errorCallback; } bool isConnecting() const { return m_connecting; } bool isConnected() const { return m_connected; } -private: +protected: void onResolve(const boost::system::error_code& error, asio::ip::tcp::resolver::iterator endpointIterator); void onConnect(const boost::system::error_code& error); void onWrite(const boost::system::error_code& error, size_t); - void onRecv(const boost::system::error_code& error); + void onRecv(const boost::system::error_code& error, size_t recvSize); void onTimeout(const boost::system::error_code& error); void handleError(const boost::system::error_code& error); @@ -71,10 +73,11 @@ private: asio::ip::tcp::resolver m_resolver; asio::ip::tcp::socket m_socket; - uint8 m_recvBuffer[65538]; - uint16 m_recvSize; + uint8 m_recvBuffer[RECV_BUFFER_SIZE]; bool m_connected; bool m_connecting; + + friend class Server; }; #endif diff --git a/src/framework/net/server.cpp b/src/framework/net/server.cpp new file mode 100644 index 00000000..11612f57 --- /dev/null +++ b/src/framework/net/server.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010-2011 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "server.h" +#include "connection.h" + +extern asio::io_service g_ioService; + +Server::Server(uint16 port) + : m_acceptor(g_ioService, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)) +{ +} + +void Server::acceptNext(const AcceptCallback& acceptCallback) +{ + ConnectionPtr connection = ConnectionPtr(new Connection); + connection->m_connecting = true; + m_acceptor.async_accept(connection->m_socket, [=](const boost::system::error_code& error) { + if(!error) { + connection->m_connected = true; + connection->m_connecting = false; + } + acceptCallback(connection, error); + }); +} diff --git a/src/framework/net/server.h b/src/framework/net/server.h new file mode 100644 index 00000000..97b3d092 --- /dev/null +++ b/src/framework/net/server.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010-2011 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef SERVER_H +#define SERVER_H + +#include "declarations.h" + +class Server +{ + typedef std::function AcceptCallback; + +public: + Server(uint16 port); + + void acceptNext(const AcceptCallback& acceptCallback); + +private: + asio::ip::tcp::acceptor m_acceptor; +}; + +#endif