E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gsocket.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 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 gsocket.h
19 ///
20
21 #ifndef G_NET_SOCKET__H
22 #define G_NET_SOCKET__H
23
24 #include "gdef.h"
25 #include "gaddress.h"
26 #include "gexception.h"
27 #include "gevent.h"
28 #include "gdescriptor.h"
29 #include "greadwrite.h"
30 #include <string>
31
32 namespace GNet
33 {
34 class Socket ;
35 class SocketProtocol ;
36 class StreamSocket ;
37 class DatagramSocket ;
38 class AcceptPair ;
39 }
40
41 /// \class GNet::Socket
42 ///
43 /// A network socket base class, holding a non-blocking socket file descriptor.
44 ///
45 /// Provides bind(), listen(), connect(), write(); derived classes provide
46 /// accept() and read(). Also interfaces to the event loop with addReadHandler()
47 /// and addWriteHandler().
48 ///
49 class GNet::Socket : public G::ReadWrite
50 {
51 public:
52 G_EXCEPTION( SocketError , "socket error" ) ;
53 G_EXCEPTION( SocketBindError , "socket bind error" ) ;
54 typedef G::ReadWrite::size_type size_type ;
55 typedef G::ReadWrite::ssize_type ssize_type ;
56 struct NoThrow /// Overload discriminator class for GNet::Socket.
57 {} ;
58 struct Accepted /// Overload discriminator class for GNet::Socket.
59 {} ;
60
61 virtual ~Socket() ;
62 ///< Destructor.
63
64 std::pair<bool,Address> getLocalAddress() const ;
65 ///< Retrieves local address of the socket.
66 ///< Pair.first is false on error.
67
68 std::pair<bool,Address> getPeerAddress() const ;
69 ///< Retrieves address of socket's peer.
70 ///< 'Pair.first' is false on error.
71
72 bool hasPeer() const ;
73 ///< Returns true if the socket has a valid peer. This
74 ///< can be used to see if a connect succeeded.
75
76 void bind( const Address & ) ;
77 ///< Binds the socket with the given address.
78
79 bool bind( const Address & , NoThrow ) ;
80 ///< No-throw overload. Returns false on error.
81
82 bool canBindHint( const Address & address ) ;
83 ///< Returns true if the socket can probably be bound
84 ///< with the given address. Some implementations will
85 ///< always return true. This method should be used on
86 ///< a temporary socket of the correct dynamic type
87 ///< since this socket may become unusable.
88
89 bool connect( const Address & addr , bool *done = nullptr ) ;
90 ///< Initiates a connection to (or association with)
91 ///< the given address. Returns false on error.
92 ///<
93 ///< If successful, a 'done' flag is returned by
94 ///< reference indicating whether the connect completed
95 ///< immediately. Normally a stream socket connection
96 ///< will take some time to complete so the 'done' flag
97 ///< will be false: the completion will be indicated by
98 ///< a write event some time later.
99 ///<
100 ///< For datagram sockets this sets up an association
101 ///< between two addresses. The socket should first be
102 ///< bound with a local address.
103
104 void listen( int backlog = 1 ) ;
105 ///< Starts the socket listening on the bound
106 ///< address for incoming connections or incoming
107 ///< datagrams.
108
109 void shutdown( int how = 1 ) ;
110 ///< Modifies the local socket state so that so that new
111 ///< sends (1 or 2) and/or receives (0 or 2) will fail.
112 ///<
113 ///< If receives are shut-down then anything received
114 ///< will be rejected with a RST.
115 ///<
116 ///< If sends are shut-down then the transmit queue is
117 ///< drained and a final empty FIN packet is sent when
118 ///< fully acknowledged.
119 ///<
120 ///< Errors are ignored.
121
122 virtual ssize_type read( char * buffer , size_type buffer_length ) override = 0 ;
123 ///< Reads from the socket.
124 ///< Override from G::ReadWrite.
125
126 virtual ssize_type write( const char * buf , size_type len ) override = 0 ;
127 ///< Writes to the socket. This is a default implementation
128 ///< that can be called explicitly from derived classes.
129 ///< Override from G::ReadWrite.
130
131 virtual SOCKET fd() const override ;
132 ///< Returns the socket descriptor. Override from G::ReadWrite.
133
134 virtual bool eWouldBlock() override ;
135 ///< Returns true if the previous socket operation
136 ///< failed because the socket would have blocked.
137 ///< Override from G::ReadWrite.
138
139 bool eInProgress() ;
140 ///< Returns true if the previous socket operation
141 ///< failed with the EINPROGRESS error status.
142 ///< When connecting this can be considered a
143 ///< non-error.
144
145 bool eMsgSize() ;
146 ///< Returns true if the previous socket operation
147 ///< failed with the EMSGSIZE error status. When
148 ///< writing to a datagram socket this indicates that
149 ///< the message was too big to send atomically.
150
151 void addReadHandler( EventHandler & , ExceptionHandler & ) ;
152 ///< Adds this socket to the event source list so that
153 ///< the given handler receives read events.
154
155 void dropReadHandler();
156 ///< Reverses addReadHandler().
157
158 void addWriteHandler( EventHandler & , ExceptionHandler & ) ;
159 ///< Adds this socket to the event source list so that
160 ///< the given handler receives write events when flow
161 ///< control is released. (Not used for datagram
162 ///< sockets.)
163
164 void dropWriteHandler() ;
165 ///< Reverses addWriteHandler().
166
167 void addOtherHandler( EventHandler & , ExceptionHandler & ) ;
168 ///< Adds this socket to the event source list so that
169 ///< the given handler receives exception events.
170 ///< A TCP exception event should be treated as a
171 ///< disconnection event. (Not used for datagram
172 ///< sockets.)
173
174 void dropOtherHandler() ;
175 ///< Reverses addOtherHandler().
176
177 std::string asString() const ;
178 ///< Returns the socket handle as a string.
179 ///< Only used in debugging.
180
181 std::string reason() const ;
182 ///< Returns the reason for the previous error.
183
184 protected:
185 Socket( int domain , int type , int protocol ) ;
186 ///< Constructor used by derived classes. Creates the
187 ///< socket using socket().
188
189 Socket( Descriptor s , const Accepted & ) ;
190 ///< Constructor which creates a socket object from
191 ///< a socket handle from accept(). Used only by
192 ///< StreamSocket::accept().
193
194 protected:
195 static std::string reasonString( int ) ;
196 static bool error( int rc ) ;
197 static bool sizeError( ssize_type size ) ;
198 bool create( int , int , int ) ;
199 void saveReason() ;
200 void saveReason() const ;
201 bool prepare( bool ) ;
202 std::pair<bool,Address> getAddress( bool ) const ;
203 void setOptionsOnBind( bool ) ;
204 void setOptionsOnConnect( bool ) ;
205 void setOptionLingerImp( int , int ) ;
206 void setOptionNoLinger() ;
207 void setOptionReuse() ;
208 void setOptionExclusive() ;
209 void setOptionPureV6( bool ) ;
210 bool setOptionPureV6( bool , NoThrow ) ;
211 void setOptionKeepAlive() ;
212
213 protected:
214 int m_reason ;
215 std::string m_reason_string ;
216 int m_domain ;
217 Descriptor m_socket ;
218 HANDLE m_handle ;
219
220 private:
221 Socket( const Socket & ) ;
222 void operator=( const Socket & ) ;
223 void drop() ;
224 void destroy() ;
225 bool setNonBlock() ;
226 void setOption( int , const char * , int , int ) ;
227 bool setOption( int , const char * , int , int , NoThrow ) ;
228 bool setOptionImp( int , int , const void * , socklen_t ) ;
229 } ;
230
231 /// \class GNet::AcceptPair
232 /// A class which is used to return a new()ed socket to calling code, together
233 /// with associated address information.
234 ///
235 class GNet::AcceptPair
236 {
237 public:
238 shared_ptr<StreamSocket> first ;
239 Address second ;
240 AcceptPair() : second(Address::defaultAddress()) {}
241 } ;
242
243 /// \class GNet::StreamSocket
244 /// A derivation of GNet::Socket for a stream socket.
245 ///
246 class GNet::StreamSocket : public Socket
247 {
248 public:
249 typedef Socket::size_type size_type ;
250 typedef Socket::ssize_type ssize_type ;
251 struct Listener /// Overload discriminator class for GNet::StreamSocket.
252 {} ;
253
254 explicit StreamSocket( int address_domain ) ;
255 ///< Constructor with a hint of the bind()/connect()
256 ///< address to be used later.
257
258 StreamSocket( int address_domain , const Listener & ) ;
259 ///< Constructor overload specifically for a listening
260 ///< socket. This can be used modify the socket options.
261
262 virtual ~StreamSocket() ;
263 ///< Destructor.
264
265 virtual ssize_type read( char * buffer , size_type buffer_length ) override ;
266 ///< Override from Socket::read().
267
268 virtual ssize_type write( const char * buf , size_type len ) override ;
269 ///< Override from Socket::write().
270
271 AcceptPair accept() ;
272 ///< Accepts an incoming connection, returning a new()ed
273 ///< socket and the peer address.
274
275 private:
276 StreamSocket( const StreamSocket & ) ; // not implemented
277 void operator=( const StreamSocket & ) ; // not implemented
278 StreamSocket( Descriptor s , const Socket::Accepted & ) ;
279 void setOptionsOnCreate( bool ) ;
280 void setOptionsOnAccept() ;
281 } ;
282
283 /// \class GNet::DatagramSocket
284 /// A derivation of GNet::Socket for a datagram socket.
285 ///
286 class GNet::DatagramSocket : public Socket
287 {
288 public:
289 explicit DatagramSocket( int address_domain ) ;
290 ///< Constructor with a hint of a local address.
291
292 virtual ~DatagramSocket() ;
293 ///< Destructor.
294
295 virtual ssize_type read( char * buffer , size_type len ) override ;
296 ///< Override from Socket::read().
297
298 virtual ssize_type write( const char * buffer , size_type len ) override ;
299 ///< Override from Socket::write().
300
301 ssize_type readfrom( char * buffer , size_type len , Address & src ) ;
302 ///< Reads a datagram and returns the sender's address by reference.
303 ///< If connect() has been used then only datagrams from the address
304 ///< specified in the connect() call will be received.
305
306 ssize_type writeto( const char * buffer , size_type len , const Address & dst ) ;
307 ///< Sends a datagram to the given address. This should be used
308 ///< if there is no connect() assocation in effect.
309
310 void disconnect() ;
311 ///< Releases the association between two datagram endpoints
312 ///< reversing the effect of the previous Socket::connect().
313
314 private:
315 DatagramSocket( const DatagramSocket & ) ;
316 void operator=( const DatagramSocket & ) ;
317 } ;
318
319 #endif
GNet::Socket::addReadHandler
void addReadHandler(EventHandler &, ExceptionHandler &)
Adds this socket to the event source list so that the given handler receives read events...
Definition: gsocket.cpp:209
GNet::Socket::canBindHint
bool canBindHint(const Address &address)
Returns true if the socket can probably be bound with the given address.
Definition: gsocket_unix.cpp:108
GNet::Socket::shutdown
void shutdown(int how=1)
Modifies the local socket state so that so that new sends (1 or 2) and/or receives (0 or 2) will fail...
Definition: gsocket.cpp:249
GNet::Socket::reason
std::string reason() const
Returns the reason for the previous error.
Definition: gsocket.cpp:260
G::ReadWrite
An abstract interface for reading and writing from a non-blocking i/o channel.
Definition: greadwrite.h:49
GNet::StreamSocket::read
virtual ssize_type read(char *buffer, size_type buffer_length) override
Override from Socket::read().
Definition: gsocket.cpp:290
GNet::Socket::getLocalAddress
std::pair< bool, Address > getLocalAddress() const
Retrieves local address of the socket.
Definition: gsocket.cpp:194
GNet::Socket::listen
void listen(int backlog=1)
Starts the socket listening on the bound address for incoming connections or incoming datagrams...
Definition: gsocket.cpp:166
GNet
Network classes.
Definition: gaddress.h:29
GNet::Socket::connect
bool connect(const Address &addr, bool *done=nullptr)
Initiates a connection to (or association with) the given address.
Definition: gsocket.cpp:112
GNet::Socket::dropReadHandler
void dropReadHandler()
Reverses addReadHandler().
Definition: gsocket.cpp:227
GNet::DatagramSocket::~DatagramSocket
virtual ~DatagramSocket()
Destructor.
Definition: gsocket.cpp:341
GNet::Socket::dropOtherHandler
void dropOtherHandler()
Reverses addOtherHandler().
Definition: gsocket.cpp:237
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:54
GNet::DatagramSocket::read
virtual ssize_type read(char *buffer, size_type len) override
Override from Socket::read().
Definition: gsocket.cpp:352
GNet::Socket
A network socket base class, holding a non-blocking socket file descriptor.
Definition: gsocket.h:49
GNet::DatagramSocket
A derivation of GNet::Socket for a datagram socket.
Definition: gsocket.h:286
GNet::StreamSocket::StreamSocket
StreamSocket(int address_domain)
Constructor with a hint of the bind()/connect() address to be used later.
Definition: gsocket.cpp:268
GNet::StreamSocket::~StreamSocket
virtual ~StreamSocket()
Destructor.
Definition: gsocket.cpp:286
GNet::Descriptor
A class that encapsulates a network socket file descriptor and an associated windows event handle...
Definition: gdescriptor.h:36
GNet::DatagramSocket::writeto
ssize_type writeto(const char *buffer, size_type len, const Address &dst)
Sends a datagram to the given address.
Definition: gsocket.cpp:381
GNet::DatagramSocket::DatagramSocket
DatagramSocket(int address_domain)
Constructor with a hint of a local address.
Definition: gsocket.cpp:336
GNet::Socket::eMsgSize
bool eMsgSize()
Returns true if the previous socket operation failed with the EMSGSIZE error status.
Definition: gsocket_unix.cpp:103
GNet::Socket::dropWriteHandler
void dropWriteHandler()
Reverses addWriteHandler().
Definition: gsocket.cpp:232
GNet::Socket::bind
void bind(const Address &)
Binds the socket with the given address.
Definition: gsocket.cpp:79
GNet::Socket::Accepted
Overload discriminator class for GNet::Socket.
Definition: gsocket.h:58
GNet::ExceptionHandler
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket events...
Definition: gexceptionhandler.h:44
GNet::DatagramSocket::disconnect
void disconnect()
Releases the association between two datagram endpoints reversing the effect of the previous Socket::...
Definition: gsocket.cpp:345
GNet::Socket::getPeerAddress
std::pair< bool, Address > getPeerAddress() const
Retrieves address of socket's peer.
Definition: gsocket.cpp:199
GNet::StreamSocket
A derivation of GNet::Socket for a stream socket.
Definition: gsocket.h:246
GNet::Socket::fd
virtual SOCKET fd() const override
Returns the socket descriptor. Override from G::ReadWrite.
Definition: gsocket.cpp:255
GNet::Address::defaultAddress
static Address defaultAddress()
Returns a default address, being the IPv4 wildcard address with a zero port number.
Definition: gaddress_ipv4.cpp:41
GNet::StreamSocket::Listener
Overload discriminator class for GNet::StreamSocket.
Definition: gsocket.h:251
GNet::DatagramSocket::write
virtual ssize_type write(const char *buffer, size_type len) override
Override from Socket::write().
Definition: gsocket.cpp:393
GNet::Socket::~Socket
virtual ~Socket()
Destructor.
Definition: gsocket.cpp:55
GNet::Socket::Socket
Socket(int domain, int type, int protocol)
Constructor used by derived classes.
Definition: gsocket.cpp:30
GNet::Socket::addOtherHandler
void addOtherHandler(EventHandler &, ExceptionHandler &)
Adds this socket to the event source list so that the given handler receives exception events...
Definition: gsocket.cpp:221
GNet::AcceptPair
A class which is used to return a new()ed socket to calling code, together with associated address in...
Definition: gsocket.h:235
gevent.h
GNet::EventHandler
A base class for classes that handle asynchronous events from the event loop.
Definition: geventhandler.h:47
GNet::Socket::write
virtual ssize_type write(const char *buf, size_type len) override=0
Writes to the socket.
Definition: gsocket.cpp:147
GNet::Socket::eInProgress
bool eInProgress()
Returns true if the previous socket operation failed with the EINPROGRESS error status.
Definition: gsocket_unix.cpp:98
GNet::Socket::hasPeer
bool hasPeer() const
Returns true if the socket has a valid peer.
Definition: gsocket.cpp:204
GNet::Socket::addWriteHandler
void addWriteHandler(EventHandler &, ExceptionHandler &)
Adds this socket to the event source list so that the given handler receives write events when flow c...
Definition: gsocket.cpp:215
GNet::StreamSocket::write
virtual ssize_type write(const char *buf, size_type len) override
Override from Socket::write().
Definition: gsocket.cpp:306
GNet::Socket::read
virtual ssize_type read(char *buffer, size_type buffer_length) override=0
Reads from the socket.
gdescriptor.h
gexception.h
gaddress.h
GNet::StreamSocket::accept
AcceptPair accept()
Accepts an incoming connection, returning a new()ed socket and the peer address.
Definition: gsocket.cpp:311
GNet::Socket::eWouldBlock
virtual bool eWouldBlock() override
Returns true if the previous socket operation failed because the socket would have blocked...
Definition: gsocket_unix.cpp:93
GNet::Socket::NoThrow
Overload discriminator class for GNet::Socket.
Definition: gsocket.h:56
greadwrite.h
GNet::DatagramSocket::readfrom
ssize_type readfrom(char *buffer, size_type len, Address &src)
Reads a datagram and returns the sender's address by reference.
Definition: gsocket.cpp:366
GNet::Socket::asString
std::string asString() const
Returns the socket handle as a string.
Definition: gsocket.cpp:242