Goby v2
tcp_server.h
1 // Copyright 2009-2018 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Goby Underwater Autonomy Project Libraries
8 // ("The Goby Libraries").
9 //
10 // The Goby Libraries are free software: you can redistribute them and/or modify
11 // them under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // The Goby Libraries are distributed in the hope that they will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
22 
23 #ifndef TCPServer20100719H
24 #define TCPServer20100719H
25 
26 #include <deque>
27 #include <iostream>
28 #include <set>
29 #include <string>
30 
31 #include <boost/asio.hpp>
32 #include <boost/bind.hpp>
33 #include <boost/enable_shared_from_this.hpp>
34 #include <boost/foreach.hpp>
35 #include <boost/shared_ptr.hpp>
36 
37 #include "goby/util/as.h"
38 
39 #include "connection.h"
40 #include "interface.h"
41 
42 namespace goby
43 {
44 namespace util
45 {
46 class TCPConnection;
47 
50 {
51  public:
56  TCPServer(unsigned port, const std::string& delimiter = "\r\n")
57  : LineBasedInterface(delimiter),
58  acceptor_(io_service(), boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
59  {
60  }
61  virtual ~TCPServer() {}
62 
63  typedef std::string Endpoint;
64  void close(const Endpoint& endpoint)
65  {
66  io_service_.post(
67  boost::bind(&TCPServer::do_close, this, boost::system::error_code(), endpoint));
68  }
69 
71  std::string local_endpoint() { return goby::util::as<std::string>(acceptor_.local_endpoint()); }
72 
73  const std::map<Endpoint, boost::shared_ptr<TCPConnection> >& connections();
74 
75  friend class TCPConnection;
76  friend class LineBasedConnection<boost::asio::ip::tcp::socket>;
77 
78  private:
79  void do_start()
80  {
81  start_accept();
82  set_active(true);
83  }
84 
85  void do_write(const protobuf::Datagram& line);
86  void do_close(const boost::system::error_code& error) { do_close(error, ""); }
87  void do_close(const boost::system::error_code& error, Endpoint endpt);
88 
89  private:
90  void start_accept();
91  void handle_accept(boost::shared_ptr<TCPConnection> new_connection,
92  const boost::system::error_code& error);
93 
94  private:
95  std::string server_;
96  boost::asio::ip::tcp::acceptor acceptor_;
97  boost::shared_ptr<TCPConnection> new_connection_;
98  std::map<Endpoint, boost::shared_ptr<TCPConnection> > connections_;
99 };
100 
101 class TCPConnection : public boost::enable_shared_from_this<TCPConnection>,
102  public LineBasedConnection<boost::asio::ip::tcp::socket>
103 {
104  public:
105  static boost::shared_ptr<TCPConnection> create(LineBasedInterface* interface);
106 
107  boost::asio::ip::tcp::socket& socket() { return socket_; }
108 
109  void start() { socket_.get_io_service().post(boost::bind(&TCPConnection::read_start, this)); }
110 
111  void write(const protobuf::Datagram& msg)
112  {
113  socket_.get_io_service().post(boost::bind(&TCPConnection::socket_write, this, msg));
114  }
115 
116  void close(const boost::system::error_code& error)
117  {
118  socket_.get_io_service().post(boost::bind(&TCPConnection::socket_close, this, error));
119  }
120 
121  std::string local_endpoint() { return goby::util::as<std::string>(socket_.local_endpoint()); }
122  std::string remote_endpoint() { return goby::util::as<std::string>(socket_.remote_endpoint()); }
123 
124  private:
125  void socket_write(const protobuf::Datagram& line);
126  void socket_close(const boost::system::error_code& error);
127 
130  socket_(interface->io_service())
131  {
132  }
133 
134  private:
135  boost::asio::ip::tcp::socket socket_;
136 };
137 } // namespace util
138 
139 } // namespace goby
140 
141 #endif
Definition: time.h:241
TCPServer(unsigned port, const std::string &delimiter="\r\n")
create a TCP server
Definition: tcp_server.h:56
provides a basic TCP server for line by line text based communications to a one or more remote TCP cl...
Definition: tcp_server.h:49
The global namespace for the Goby project.
std::string local_endpoint()
string representation of the local endpoint (e.g. 192.168.1.105:54230
Definition: tcp_server.h:71
basic interface class for all the derived serial (and networking mimics) line-based nodes (serial...
Definition: interface.h:44