E-MailRelay
gserver.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 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 "geventstate.h"
28#include "gexception.h"
29#include "gsocket.h"
30#include "glistener.h"
31#include "glimits.h"
32#include "gprocess.h"
33#include "gevent.h"
34#include <utility>
35#include <memory>
36#include <string>
37
38namespace GNet
39{
40 class Server ;
41 class ServerPeer ;
42 class ServerPeerInfo ;
43}
44
45//| \class GNet::Server
46/// A network server class which listens on a specific port and spins off
47/// ServerPeer objects for each incoming connection.
48/// \see GNet::ServerPeer
49///
50class GNet::Server : public Listener, private EventHandler, private ExceptionHandler
51{
52public:
53 G_EXCEPTION( CannotBind , tx("cannot bind the listening port") )
54
55 struct Config /// A configuration structure for GNet::Server.
56 {
57 StreamSocket::Config stream_socket_config ;
58 bool uds_open_permissions {false} ;
59 Config & set_stream_socket_config( const StreamSocket::Config & ) ;
60 Config & set_uds_open_permissions( bool b = true ) noexcept ;
61 } ;
62
63 Server( EventState , const Address & listening_address , const ServerPeer::Config & , const Config & ) ;
64 ///< Constructor. The server listens on the given address,
65 ///< which can be the 'any' address. The EventState
66 ///< is used for exceptions relating to the listening
67 ///< socket, not the server peers.
68
69 Server( EventState , Descriptor listening_fd , const ServerPeer::Config & , const Config & ) ;
70 ///< Constructor overload for adopting an externally-managed
71 ///< listening file descriptor.
72
73 ~Server() override ;
74 ///< Destructor.
75
76 Address address() const override ;
77 ///< Returns the listening address.
78 ///< Override from GNet::Listener.
79
80 std::vector<std::weak_ptr<GNet::ServerPeer>> peers() ;
81 ///< Returns the list of ServerPeer objects. The
82 ///< returned ServerPeer objects must not outlive
83 ///< this Server.
84
85 bool hasPeers() const ;
86 ///< Returns true if peers() is not empty.
87
88protected:
89 virtual std::unique_ptr<ServerPeer> newPeer( EventStateUnbound , ServerPeerInfo && ) = 0 ;
90 ///< A factory method which new()s a ServerPeer-derived
91 ///< object. This method is called when a new connection
92 ///< comes in to this server. The new ServerPeer object
93 ///< is used to represent the state of the client/server
94 ///< connection.
95 ///<
96 ///< The implementation should std::move the 'ServerPeerInfo'
97 ///< parameter through to the ServerPeer base-class
98 ///< constructor.
99 ///<
100 ///< The implementation should return nullptr for non-fatal
101 ///< errors. It is expected that a typical server process will
102 ///< terminate if newPeer() throws, so most implementations
103 ///< will catch any exceptions and return nullptr.
104
105 void serverCleanup() ;
106 ///< Should be called by the most-derived class's
107 ///< destructor in order to trigger early deletion of
108 ///< peer objects before the derived part of the server
109 ///< disappears. This prevents slicing if the destructor
110 ///< of the most-derived ServerPeer makes use of the
111 ///< most-derived Server.
112
113private: // overrides
114 void readEvent() override ; // Override from GNet::EventHandler.
115 void writeEvent() override ; // Override from GNet::EventHandler.
116 void onException( ExceptionSource * , std::exception & , bool ) override ; // Override from GNet::ExceptionHandler.
117
118public:
119 Server( const Server & ) = delete ;
120 Server( Server && ) = delete ;
121 Server & operator=( const Server & ) = delete ;
122 Server & operator=( Server && ) = delete ;
123
124private:
125 void accept( ServerPeerInfo & ) ;
126
127private:
128 using PeerList = std::vector<std::shared_ptr<ServerPeer>> ;
129 EventState m_es ;
130 Config m_config ;
131 ServerPeer::Config m_server_peer_config ;
132 StreamSocket m_socket ; // listening socket
133 PeerList m_peer_list ;
134 std::string m_event_logging_string ;
135} ;
136
137//| \class GNet::ServerPeerInfo
138/// A move-only structure used in GNet::Server::newPeer() and
139/// containing the new socket.
140///
142{
143public:
144 std::unique_ptr<StreamSocket> m_socket ;
145 Address m_address ;
146 ServerPeer::Config m_server_peer_config ;
147 Server * m_server ;
149} ;
150
151inline GNet::Server::Config & GNet::Server::Config::set_stream_socket_config( const StreamSocket::Config & c ) { stream_socket_config = c ; return *this ; }
152inline GNet::Server::Config & GNet::Server::Config::set_uds_open_permissions( bool b ) noexcept { uds_open_permissions = b ; return *this ; }
153
154#endif
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:63
A class that encapsulates a network socket file descriptor and an associated windows event handle.
Definition: gdescriptor.h:37
A base class for classes that have a file descriptor and handle asynchronous events from the event lo...
Definition: geventhandler.h:48
The EventStateUnbound class is used as a device to force factory methods to plumb-in an ExceptionSour...
Definition: geventstate.h:231
A lightweight object containing an ExceptionHandler pointer, optional ExceptionSource pointer and opt...
Definition: geventstate.h:131
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket/future event...
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 move-only structure used in GNet::Server::newPeer() and containing the new socket.
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:51
~Server() override
Destructor.
Definition: gserver.cpp:89
Address address() const override
Returns the listening address.
Definition: gserver.cpp:94
bool hasPeers() const
Returns true if peers() is not empty.
Definition: gserver.cpp:184
Server(EventState, const Address &listening_address, const ServerPeer::Config &, const Config &)
Constructor.
Definition: gserver.cpp:50
virtual std::unique_ptr< ServerPeer > newPeer(EventStateUnbound, ServerPeerInfo &&)=0
A factory method which new()s a ServerPeer-derived object.
std::vector< std::weak_ptr< GNet::ServerPeer > > peers()
Returns the list of ServerPeer objects.
Definition: gserver.cpp:189
void serverCleanup()
Should be called by the most-derived class's destructor in order to trigger early deletion of peer ob...
Definition: gserver.cpp:179
A derivation of GNet::Socket for a stream socket.
Definition: gsocket.h:356
Network classes.
Definition: gdef.h:1243
constexpr const char * tx(const char *p) noexcept
A briefer alternative to G::gettext_noop().
Definition: ggettext.h:84
A configuration structure for GNet::ServerPeer.
Definition: gserverpeer.h:64
A configuration structure for GNet::Server.
Definition: gserver.h:56
A configuration structure for GNet::StreamSocket.
Definition: gsocket.h:363