Note: Goby version 1 (shown here) is now considered obsolete. Please use version 2 for new projects, and consider upgrading old projects.

Goby Underwater Autonomy Project  Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
util/liblinebasedcomms/tcp_server.h
00001 // copyright 2010 t. schneider tes@mit.edu
00002 //
00003 //
00004 // This program is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // This software is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this software.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 
00018 #ifndef TCPServer20100719H
00019 #define TCPServer20100719H
00020 
00021 #include <iostream>
00022 #include <string>
00023 #include <set>
00024 #include <deque>
00025 
00026 #include <boost/bind.hpp>
00027 #include <boost/shared_ptr.hpp>
00028 #include <boost/enable_shared_from_this.hpp>
00029 #include <boost/foreach.hpp>
00030 #include <boost/asio.hpp>
00031 
00032 #include "goby/util/string.h"
00033 
00034 #include "interface.h"
00035 #include "connection.h"
00036 
00037 namespace goby
00038 {
00039     namespace util
00040     {
00041         class TCPConnection;
00042         
00044         class TCPServer : public LineBasedInterface
00045         {
00046           public:
00051           TCPServer(unsigned port,
00052                     const std::string& delimiter = "\r\n")
00053               : LineBasedInterface(delimiter),
00054                 acceptor_(LineBasedInterface::io_service_,
00055                           boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
00056                 {  }
00057 
00059             std::string local_endpoint() { return goby::util::as<std::string>(acceptor_.local_endpoint()); }
00060 
00061             
00062 
00063             // for access to static members of LineBasedInterface
00064             friend class TCPConnection;
00065             friend class LineBasedConnection<boost::asio::ip::tcp::socket>;
00066           private:
00067             void do_start()
00068             { start_accept(); }
00069         
00070             void do_write(const protobuf::Datagram& line);
00071             void do_close(const boost::system::error_code& error);
00072             
00073           private:
00074             void start_accept();
00075             void handle_accept(boost::shared_ptr<TCPConnection> new_connection,
00076                                const boost::system::error_code& error);
00077             
00078           private:
00079             static std::map<std::string, TCPServer*> inst_;
00080             std::string server_;
00081             boost::asio::ip::tcp::acceptor acceptor_;
00082             boost::shared_ptr<TCPConnection> new_connection_;
00083             std::set< boost::shared_ptr<TCPConnection> > connections_;    
00084         };
00085 
00086 
00087         class TCPConnection : public boost::enable_shared_from_this<TCPConnection>,
00088             public LineBasedConnection<boost::asio::ip::tcp::socket>
00089             {
00090               public:
00091                 static boost::shared_ptr<TCPConnection> create();
00092                 
00093                 boost::asio::ip::tcp::socket& socket()
00094                 { return socket_; }
00095     
00096                 void start()
00097                 { socket_.get_io_service().post(boost::bind(&TCPConnection::read_start, this)); }
00098 
00099                 void write(const protobuf::Datagram& msg)
00100                 { socket_.get_io_service().post(boost::bind(&TCPConnection::socket_write, this, msg)); }    
00101 
00102                 void close(const boost::system::error_code& error)
00103                 { socket_.get_io_service().post(boost::bind(&TCPConnection::socket_close, this, error)); }
00104                 
00105                 std::string local_endpoint() { return goby::util::as<std::string>(socket_.local_endpoint()); }
00106                 std::string remote_endpoint() { return goby::util::as<std::string>(socket_.remote_endpoint()); }
00107                 
00108               private:
00109                 void socket_write(const protobuf::Datagram& line);
00110                 void socket_close(const boost::system::error_code& error);
00111     
00112               TCPConnection()
00113                   : socket_(LineBasedInterface::io_service_)
00114                 { }
00115     
00116 
00117               private:
00118                 boost::asio::ip::tcp::socket socket_;
00119             };
00120     }
00121 
00122 }
00123 
00124 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends