E-MailRelay
gserver.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gserver.h
19///
20
21#ifndef G_NET_SERVER_H
22#define G_NET_SERVER_H
23
24#include "gdef.h"
25#include "ggettext.h"
26#include "gserverpeer.h"
27#include "gexceptionsink.h"
28#include "gexception.h"
29#include "gsocket.h"
30#include "glistener.h"
31#include "glimits.h"
32#include "gevent.h"
33#include <utility>
34#include <memory>
35#include <string>
36
37namespace GNet
38{
39 struct ServerConfig ;
40 class Server ;
41 class ServerPeer ;
42 class ServerPeerConfig ;
43 class ServerPeerInfo ;
44}
45
46//| \class GNet::ServerConfig
47/// A configuration structure for GNet::Server.
48///
50{
51 int listen_queue { G::limits::net_listen_queue } ; // Socket::listen() 'backlog'
52 bool uds_open_permissions { true } ;
53 ServerConfig & set_uds_open_permissions( bool b = true ) ;
54} ;
55
56//| \class GNet::Server
57/// A network server class which listens on a specific port and spins off
58/// ServerPeer objects for each incoming connection.
59/// \see GNet::ServerPeer
60///
61class GNet::Server : public Listener, private EventHandler, private ExceptionHandler
62{
63public:
64 G_EXCEPTION( CannotBind , G::gettext_noop("cannot bind the listening port") ) ;
65
66 Server( ExceptionSink , const Address & listening_address , ServerPeerConfig , ServerConfig ) ;
67 ///< Constructor. The server listens on the given address,
68 ///< which can be the 'any' address. The ExceptionSink
69 ///< is used for exceptions relating to the listening
70 ///< socket, not the server peers.
71
72 ~Server() override ;
73 ///< Destructor.
74
75 Address address() const override ;
76 ///< Returns the listening address.
77 ///< Override from GNet::Listener.
78
79 static bool canBind( const Address & listening_address , bool do_throw ) ;
80 ///< Checks that the specified address can be
81 ///< bound. Throws CannotBind if the address cannot
82 ///< be bound and 'do_throw' is true.
83
84 std::vector<std::weak_ptr<GNet::ServerPeer> > peers() ;
85 ///< Returns the list of ServerPeer objects.
86
87 bool hasPeers() const ;
88 ///< Returns true if peers() is not empty.
89
90protected:
91 virtual std::unique_ptr<ServerPeer> newPeer( ExceptionSinkUnbound , ServerPeerInfo ) = 0 ;
92 ///< A factory method which new()s a ServerPeer-derived
93 ///< object. This method is called when a new connection
94 ///< comes in to this server. The new ServerPeer object
95 ///< is used to represent the state of the client/server
96 ///< connection.
97 ///<
98 ///< The implementation should pass the 'ServerPeerInfo'
99 ///< parameter through to the ServerPeer base-class
100 ///< constructor.
101 ///<
102 ///< The implementation should return nullptr for non-fatal
103 ///< errors. It is expected that a typical server process will
104 ///< terminate if newPeer() throws, so most implementations
105 ///< will catch any exceptions and return nullptr.
106
107 void serverCleanup() ;
108 ///< Should be called by the most-derived class's
109 ///< destructor in order to trigger early deletion of
110 ///< peer objects before the derived part of the server
111 ///< disappears. This prevents slicing if the destructor
112 ///< of the most-derived ServerPeer makes use of the
113 ///< most-derived Server.
114
115private: // overrides
116 void readEvent() override ; // Override from GNet::EventHandler.
117 void writeEvent() override ; // Override from GNet::EventHandler.
118 void onException( ExceptionSource * , std::exception & , bool ) override ; // Override from GNet::ExceptionHandler.
119
120public:
121 Server( const Server & ) = delete ;
122 Server( Server && ) = delete ;
123 void operator=( const Server & ) = delete ;
124 void operator=( Server && ) = delete ;
125
126private:
127 void accept( ServerPeerInfo & ) ;
128 static bool unlink( G::SignalSafe , const char * ) noexcept ;
129
130private:
131 using PeerList = std::vector<std::shared_ptr<ServerPeer> > ;
132 ExceptionSink m_es ;
133 ServerPeerConfig m_server_peer_config ;
134 StreamSocket m_socket ; // listening socket
135 PeerList m_peer_list ;
136} ;
137
138//| \class GNet::ServerPeerInfo
139/// A structure used in GNet::Server::newPeer().
140///
142{
143public:
144 std::shared_ptr<StreamSocket> m_socket ;
145 Address m_address ;
146 ServerPeerConfig m_config ;
147 Server * m_server ;
149} ;
150
151inline GNet::ServerConfig & GNet::ServerConfig::set_uds_open_permissions( bool b ) { uds_open_permissions = b ; return *this ; }
152
153#endif
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
A base class for classes that handle asynchronous events from the event loop.
Definition: geventhandler.h:48
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket/future event...
A potential ExceptionSink that is realised by bind()ing an exception source pointer.
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
A mixin base class that identifies the source of an exception when delivered to GNet::ExceptionHandle...
An interface for a network listener.
Definition: glistener.h:37
A structure that GNet::Server uses to configure its ServerPeer objects.
Definition: gserverpeer.h:51
A structure used in GNet::Server::newPeer().
Definition: gserver.h:142
A network server class which listens on a specific port and spins off ServerPeer objects for each inc...
Definition: gserver.h:62
~Server() override
Destructor.
Definition: gserver.cpp:72
Address address() const override
Returns the listening address.
Definition: gserver.cpp:89
bool hasPeers() const
Returns true if peers() is not empty.
Definition: gserver.cpp:179
virtual std::unique_ptr< ServerPeer > newPeer(ExceptionSinkUnbound, ServerPeerInfo)=0
A factory method which new()s a ServerPeer-derived object.
Server(ExceptionSink, const Address &listening_address, ServerPeerConfig, ServerConfig)
Constructor.
Definition: gserver.cpp:34
std::vector< std::weak_ptr< GNet::ServerPeer > > peers()
Returns the list of ServerPeer objects.
Definition: gserver.cpp:184
void serverCleanup()
Should be called by the most-derived class's destructor in order to trigger early deletion of peer ob...
Definition: gserver.cpp:174
static bool canBind(const Address &listening_address, bool do_throw)
Checks that the specified address can be bound.
Definition: gserver.cpp:77
A derivation of GNet::Socket for a stream socket.
Definition: gsocket.h:311
An empty structure that is used to indicate a signal-safe, reentrant implementation.
Definition: gsignalsafe.h:37
Network classes.
Definition: gdef.h:1115
constexpr const char * gettext_noop(const char *p)
Marks a string for translation at build-time, but no translation is applied at run-time.
Definition: ggettext.h:75
A configuration structure for GNet::Server.
Definition: gserver.h:50