summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@sakuya.local>2010-11-06 02:35:39 +0100
committerVegard Storheil Eriksen <zyp@sakuya.local>2010-11-06 02:35:39 +0100
commitcfef24ce8541ac3934ecfe7248a33d1099d94dfa (patch)
tree4335e25b6fd490fa8744fed82aa7273fc7a72395
parentdf5932614261a825fb5a9283c321f47f7a198b24 (diff)
First take on abstract ConnectionBase, ASIO listening and connection handling.
-rw-r--r--common/connectionbase.cpp16
-rw-r--r--common/connectionbase.h40
-rw-r--r--server/SConstruct8
-rw-r--r--server/connection.cpp35
-rw-r--r--server/connection.h38
-rw-r--r--server/main.cpp58
-rw-r--r--server/tcpserver.cpp28
-rw-r--r--server/tcpserver.h22
8 files changed, 185 insertions, 60 deletions
diff --git a/common/connectionbase.cpp b/common/connectionbase.cpp
new file mode 100644
index 0000000..b2147fa
--- /dev/null
+++ b/common/connectionbase.cpp
@@ -0,0 +1,16 @@
+#include "connectionbase.h"
+
+#include <iostream>
+#include <string>
+
+void ConnectionBase::connected() {
+ std::cout << "Connection established." << std::endl;
+
+ write_data((uint8_t*)"Hei!\n", 5);
+
+ request_data(10);
+}
+
+void ConnectionBase::got_data(uint8_t* data, std::size_t bytes) {
+ std::cout << "Fikk data: " << std::string((char*)data, bytes) << std::endl;
+}
diff --git a/common/connectionbase.h b/common/connectionbase.h
new file mode 100644
index 0000000..1bfc437
--- /dev/null
+++ b/common/connectionbase.h
@@ -0,0 +1,40 @@
+#ifndef CONNECTIONBASE_H
+#define CONNECTIONBASE_H
+
+#include <stdint.h>
+#include <cstdlib>
+
+// Poor excuse for a real Message class.
+class Message {
+ public:
+ typedef Message* p;
+};
+
+class ConnectionBase {
+ protected:
+ //! Signal that connection is established and ready to transfer data.
+ void connected();
+
+ //! Deliver received data.
+ //! \param data Pointer to received data. Ownership is retained by caller.
+ //! \param bytes Size of data.
+ void got_data(uint8_t* data, std::size_t bytes);
+
+ //! Called to request data.
+ //! \param bytes Amount of data requested.
+ virtual void request_data(std::size_t bytes) = 0;
+
+ //! Called to write data.
+ //! \param data Pointer to data to send. Ownership is transferred to callee.
+ //! \param bytes Size of data.
+ virtual void write_data(uint8_t* data, std::size_t bytes) = 0;
+
+ public:
+ //! Send a message.
+ void send(const Message::p& msg);
+
+ //! Get received message or null if queue empty.
+ Message::p recv();
+};
+
+#endif
diff --git a/server/SConstruct b/server/SConstruct
index d1def28..fe7244e 100644
--- a/server/SConstruct
+++ b/server/SConstruct
@@ -10,14 +10,14 @@ AddOption('--profiling', action = 'store_true')
env.Append(LIBS = ['boost_system', 'pthread'])
if not GetOption('release'):
- env.Append(CPPFLAGS = ['-Wall', '-g'])
+ env.Append(CPPFLAGS = ['-Wall', '-g'])
if GetOption('profiling'):
- env.Append(CPPFLAGS = ['-pg'])
- env.Append(LINKFLAGS = ['-pg'])
+ env.Append(CPPFLAGS = ['-pg'])
+ env.Append(LINKFLAGS = ['-pg'])
Export('env')
-env.Program('aotenjoud', Glob('*.cpp'))
+env.Program('aotenjoud', Glob('*.cpp') + ['../common/connectionbase.cpp'])
# vim: syn=python
diff --git a/server/connection.cpp b/server/connection.cpp
new file mode 100644
index 0000000..f846d3b
--- /dev/null
+++ b/server/connection.cpp
@@ -0,0 +1,35 @@
+#include "connection.h"
+
+#include <boost/bind.hpp>
+
+Connection::Connection(boost::asio::io_service& io_service) : socket(io_service) {
+
+}
+
+void Connection::handle_read(uint8_t* data, std::size_t bytes) {
+ got_data(data, bytes);
+
+ delete[] data;
+}
+
+void Connection::handle_write() {
+
+}
+
+void Connection::request_data(std::size_t bytes) {
+ uint8_t* buf = new uint8_t[bytes];
+
+ boost::asio::async_read(socket, boost::asio::buffer(buf, bytes),
+ boost::bind(&Connection::handle_read, shared_from_this(), buf, bytes));
+
+ // boost::asio::placeholders::error
+}
+
+void Connection::write_data(uint8_t* data, std::size_t bytes) {
+ boost::asio::async_write(socket, boost::asio::buffer(data, bytes),
+ boost::bind(&Connection::handle_write, shared_from_this()));
+}
+
+Connection::p Connection::create(boost::asio::io_service& io_service) {
+ return Connection::p(new Connection(io_service));
+}
diff --git a/server/connection.h b/server/connection.h
new file mode 100644
index 0000000..aba7734
--- /dev/null
+++ b/server/connection.h
@@ -0,0 +1,38 @@
+#ifndef CONNECTION_H
+#define CONNECTION_H
+
+#include <boost/asio.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include "../common/connectionbase.h"
+
+class Connection : public ConnectionBase, public boost::enable_shared_from_this<Connection> {
+ private:
+ friend class TCPServer;
+
+ boost::asio::ip::tcp::socket socket;
+
+ Connection(boost::asio::io_service& io_service);
+
+ private:
+ //! Callback for when data is read.
+ void handle_read(uint8_t* data, std::size_t bytes);
+
+ //! Callback for when data is written.
+ void handle_write();
+
+ protected:
+ //! Implements request_data().
+ virtual void request_data(std::size_t bytes);
+
+ //! Implements write_data().
+ virtual void write_data(uint8_t* data, std::size_t bytes);
+
+ public:
+ typedef boost::shared_ptr<Connection> p;
+
+ //! Constructs a new instance and returns a shared pointer.
+ static p create(boost::asio::io_service& io_service);
+};
+
+#endif
diff --git a/server/main.cpp b/server/main.cpp
index 9341623..3e311e5 100644
--- a/server/main.cpp
+++ b/server/main.cpp
@@ -1,67 +1,13 @@
#include <iostream>
-#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
-using boost::asio::ip::tcp;
-
-class tcp_connection : public boost::enable_shared_from_this<tcp_connection> {
- public:
- typedef boost::shared_ptr<tcp_connection> pointer;
-
- static pointer create(boost::asio::io_service& io_service) {
- return pointer(new tcp_connection(io_service));
- }
-
- tcp::socket& socket() {
- return socket_;
- }
-
- void start() {
- boost::asio::async_write(socket_, boost::asio::buffer("Hei!\n"),
- boost::bind(&tcp_connection::handle_write, shared_from_this()));
- }
-
- private:
- tcp::socket socket_;
-
- tcp_connection(boost::asio::io_service& io_service) : socket_(io_service) {
- }
-
- void handle_write() {
- }
-};
-
-class tcp_server {
- public:
- tcp_server(boost::asio::io_service& io_service)
- : acceptor_(io_service, tcp::endpoint(tcp::v4(), 12345)) {
- start_accept();
- }
-
- private:
- tcp::acceptor acceptor_;
-
- void start_accept() {
- tcp_connection::pointer new_connection = tcp_connection::create(acceptor_.io_service());
-
- acceptor_.async_accept(new_connection->socket(), boost::bind(&tcp_server::handle_accept, this, new_connection, boost::asio::placeholders::error));
- }
-
- void handle_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error) {
- if(!error) {
- new_connection->start();
- start_accept();
- }
- }
-};
+#include "tcpserver.h"
int main() {
try {
boost::asio::io_service io_service;
- tcp_server server(io_service);
+ TCPServer server(io_service);
std::cout << "Listening to port 12345" << std::endl;
diff --git a/server/tcpserver.cpp b/server/tcpserver.cpp
new file mode 100644
index 0000000..528d1a2
--- /dev/null
+++ b/server/tcpserver.cpp
@@ -0,0 +1,28 @@
+#include "tcpserver.h"
+
+#include <boost/bind.hpp>
+
+TCPServer::TCPServer(boost::asio::io_service& io_service)
+ : acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 12345)) {
+
+ // Start listening for first connection attempt.
+ listen();
+}
+
+void TCPServer::listen() {
+ Connection::p new_connection = Connection::create(acceptor_.io_service());
+
+ acceptor_.async_accept(new_connection->socket,
+ boost::bind(&TCPServer::handle_connection, this, new_connection, boost::asio::placeholders::error));
+}
+
+void TCPServer::handle_connection(Connection::p connection, const boost::system::error_code& error) {
+ if(error) {
+ return;
+ }
+
+ connection->connected();
+
+ // Start listening for another connection attempt.
+ listen();
+} \ No newline at end of file
diff --git a/server/tcpserver.h b/server/tcpserver.h
new file mode 100644
index 0000000..5d0cbba
--- /dev/null
+++ b/server/tcpserver.h
@@ -0,0 +1,22 @@
+#ifndef TCPSERVER_H
+#define TCPSERVER_H
+
+#include <boost/asio.hpp>
+
+#include "connection.h"
+
+class TCPServer {
+ private:
+ boost::asio::ip::tcp::acceptor acceptor_;
+
+ //! Listen for incoming connection.
+ void listen();
+
+ //! Handle new connection.
+ void handle_connection(Connection::p connection, const boost::system::error_code& error);
+
+ public:
+ TCPServer(boost::asio::io_service& io_service);
+};
+
+#endif