E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gsocket.cpp
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 // gsocket.cpp
19 //
20
21 #include "gdef.h"
22 #include "gsocket.h"
23 #include "gtest.h"
24 #include "gsleep.h"
25 #include "gmsg.h"
26 #include "gstr.h"
27 #include "gdebug.h"
28 #include "gassert.h"
29
30 GNet::Socket::Socket( int domain , int type , int protocol ) :
31 m_reason(0) ,
32 m_domain(domain)
33 {
34 if( !create(domain,type,protocol ) )
35 throw SocketError( "cannot create socket" , m_reason_string ) ;
36
37 if( !prepare(false) )
38 {
39 destroy() ;
40 throw SocketError( "cannot prepare socket" , m_reason_string ) ;
41 }
42 }
43
44 GNet::Socket::Socket( Descriptor s , const Accepted & ) :
45 m_reason(0) ,
46 m_socket(s)
47 {
48 if( !prepare(true) )
49 {
50 destroy() ;
51 throw SocketError( "cannot prepare socket" , m_reason_string ) ;
52 }
53 }
54
55 GNet::Socket::~Socket()
56 {
57 try
58 {
59 drop() ;
60 destroy() ;
61 }
62 catch(...) // dtor
63 {
64 }
65 }
66
67 void GNet::Socket::drop()
68 {
69 dropReadHandler() ;
70 dropWriteHandler() ;
71 dropOtherHandler() ;
72 }
73
74 void GNet::Socket::saveReason() const
75 {
76 const_cast<GNet::Socket*>(this)->saveReason() ;
77 }
78
79 void GNet::Socket::bind( const Address & local_address )
80 {
81 G_DEBUG( "Socket::bind: binding " << local_address.displayString() << " on fd " << m_socket ) ;
82
83 if( local_address.domain() != m_domain )
84 throw SocketBindError( "address family does not match the socket domain" ) ;
85
86 setOptionsOnBind( local_address.family() == Address::Family::ipv6() ) ;
87
88 int rc = ::bind( m_socket.fd() , local_address.address() , local_address.length() ) ;
89 if( error(rc) )
90 {
91 saveReason() ;
92 throw SocketBindError( local_address.displayString() , m_reason_string ) ;
93 }
94 }
95
96 bool GNet::Socket::bind( const Address & local_address , NoThrow )
97 {
98 G_DEBUG( "Socket::bind: binding " << local_address.displayString() << " on fd " << m_socket ) ;
99 if( local_address.domain() != m_domain ) return false ;
100
101 setOptionsOnBind( local_address.family() == Address::Family::ipv6() ) ;
102
103 int rc = ::bind( m_socket.fd() , local_address.address() , local_address.length() ) ;
104 if( error(rc) )
105 {
106 saveReason() ;
107 return false ;
108 }
109 return true ;
110 }
111
112 bool GNet::Socket::connect( const Address & address , bool *done )
113 {
114 G_DEBUG( "GNet::Socket::connect: connecting to " << address.displayString() ) ;
115 if( address.domain() != m_domain )
116 {
117 G_WARNING( "GNet::Socket::connect: cannot connect: address family does not match "
118 "the socket domain (" << address.domain() << "," << m_domain << ")" ) ;
119 return false ;
120 }
121
122 setOptionsOnConnect( address.family() == Address::Family::ipv6() ) ;
123
124 int rc = ::connect( m_socket.fd() , address.address() , address.length() ) ;
125 if( error(rc) )
126 {
127 saveReason() ;
128
129 if( G::Test::enabled("socket-slow-connect") )
130 sleep( 1 ) ;
131
132 if( eInProgress() )
133 {
134 G_DEBUG( "GNet::Socket::connect: connection in progress" ) ;
135 if( done != nullptr ) *done = false ;
136 return true ;
137 }
138
139 G_DEBUG( "GNet::Socket::connect: synchronous connect failure: " << m_reason ) ;
140 return false;
141 }
142
143 if( done != nullptr ) *done = true ;
144 return true ;
145 }
146
147 GNet::Socket::ssize_type GNet::Socket::write( const char * buf , size_type len )
148 {
149 if( static_cast<ssize_type>(len) < 0 )
150 G_WARNING( "GNet::Socket::write: too big" ) ; // should get EMSGSIZE from ::send()
151
152 ssize_type nsent = G::Msg::send( m_socket.fd() , buf , len , MSG_NOSIGNAL ) ;
153 if( sizeError(nsent) ) // if -1
154 {
155 saveReason() ;
156 G_DEBUG( "GNet::Socket::write: write error " << m_reason ) ;
157 return -1 ;
158 }
159 else if( nsent < 0 || static_cast<size_type>(nsent) < len )
160 {
161 saveReason() ;
162 }
163 return nsent;
164 }
165
166 void GNet::Socket::listen( int backlog )
167 {
168 int rc = ::listen( m_socket.fd() , backlog ) ;
169 if( error(rc) )
170 {
171 saveReason() ;
172 throw SocketError( "cannot listen on socket" , m_reason_string ) ;
173 }
174 }
175
176 std::pair<bool,GNet::Address> GNet::Socket::getAddress( bool local ) const
177 {
178 std::pair<bool,Address> error_pair( false , Address::defaultAddress() ) ;
179 AddressStorage address_storage ;
180 int rc =
181 local ?
182 ::getsockname( m_socket.fd() , address_storage.p1() , address_storage.p2() ) :
183 ::getpeername( m_socket.fd() , address_storage.p1() , address_storage.p2() ) ;
184
185 if( error(rc) )
186 {
187 saveReason() ;
188 return error_pair ;
189 }
190
191 return std::pair<bool,Address>( true , Address(address_storage) ) ;
192 }
193
194 std::pair<bool,GNet::Address> GNet::Socket::getLocalAddress() const
195 {
196 return getAddress( true ) ;
197 }
198
199 std::pair<bool,GNet::Address> GNet::Socket::getPeerAddress() const
200 {
201 return getAddress( false ) ;
202 }
203
204 bool GNet::Socket::hasPeer() const
205 {
206 return getPeerAddress().first ;
207 }
208
209 void GNet::Socket::addReadHandler( EventHandler & handler , ExceptionHandler & eh )
210 {
211 G_DEBUG( "GNet::Socket::addReadHandler: fd " << m_socket ) ;
212 EventLoop::instance().addRead( m_socket , handler , eh ) ;
213 }
214
215 void GNet::Socket::addWriteHandler( EventHandler & handler , ExceptionHandler & eh )
216 {
217 G_DEBUG( "GNet::Socket::addWriteHandler: fd " << m_socket ) ;
218 EventLoop::instance().addWrite( m_socket , handler , eh ) ;
219 }
220
221 void GNet::Socket::addOtherHandler( EventHandler & handler , ExceptionHandler & eh )
222 {
223 G_DEBUG( "GNet::Socket::addOtherHandler: fd " << m_socket ) ;
224 EventLoop::instance().addOther( m_socket , handler , eh ) ;
225 }
226
227 void GNet::Socket::dropReadHandler()
228 {
229 EventLoop::instance().dropRead( m_socket ) ;
230 }
231
232 void GNet::Socket::dropWriteHandler()
233 {
234 EventLoop::instance().dropWrite( m_socket ) ;
235 }
236
237 void GNet::Socket::dropOtherHandler()
238 {
239 EventLoop::instance().dropOther( m_socket ) ;
240 }
241
242 std::string GNet::Socket::asString() const
243 {
244 std::ostringstream ss ;
245 ss << m_socket ;
246 return ss.str() ;
247 }
248
249 void GNet::Socket::shutdown( int how )
250 {
251 if( G::Test::enabled("socket-no-shutdown") ) return ;
252 ::shutdown( m_socket.fd() , how ) ;
253 }
254
255 SOCKET GNet::Socket::fd() const
256 {
257 return m_socket.fd() ;
258 }
259
260 std::string GNet::Socket::reason() const
261 {
262 if( m_reason == 0 ) return std::string() ;
263 return reasonString( m_reason ) ;
264 }
265
266 //==
267
268 GNet::StreamSocket::StreamSocket( int address_domain ) :
269 Socket(address_domain,SOCK_STREAM,0)
270 {
271 setOptionsOnCreate( false ) ;
272 }
273
274 GNet::StreamSocket::StreamSocket( int address_domain , const Listener & ) :
275 Socket(address_domain,SOCK_STREAM,0)
276 {
277 setOptionsOnCreate( true ) ;
278 }
279
280 GNet::StreamSocket::StreamSocket( Descriptor s , const Socket::Accepted & accepted ) :
281 Socket(s,accepted)
282 {
283 setOptionsOnAccept() ;
284 }
285
286 GNet::StreamSocket::~StreamSocket()
287 {
288 }
289
290 GNet::Socket::ssize_type GNet::StreamSocket::read( char * buf , size_type len )
291 {
292 if( len == 0 )
293 return 0 ;
294
295 m_reason = 0 ;
296 ssize_type nread = G::Msg::recv( m_socket.fd() , buf , len , 0 ) ;
297 if( sizeError(nread) )
298 {
299 saveReason() ;
300 G_DEBUG( "GNet::StreamSocket::read: cannot read from " << m_socket.fd() ) ;
301 return -1 ;
302 }
303 return nread ;
304 }
305
306 GNet::Socket::ssize_type GNet::StreamSocket::write( const char * buf , size_type len )
307 {
308 return Socket::write( buf , len ) ;
309 }
310
311 GNet::AcceptPair GNet::StreamSocket::accept()
312 {
313 AddressStorage addr ;
314 Descriptor new_fd( ::accept(m_socket.fd(),addr.p1(),addr.p2()) ) ;
315 if( ! new_fd.valid() )
316 {
317 saveReason() ;
318 throw SocketError( "cannot accept on socket" , m_reason_string ) ;
319 }
320
321 if( G::Test::enabled("socket-accept-throws") )
322 throw SocketError( "testing" ) ;
323
324 AcceptPair pair ;
325 pair.second = Address( addr.p() , addr.n() ) ;
326 pair.first.reset( new StreamSocket(new_fd,Socket::Accepted()) ) ;
327
328 G_DEBUG( "GNet::StreamSocket::accept: accepted from " << m_socket.fd()
329 << " to " << new_fd << " (" << pair.second.displayString() << ")" ) ;
330
331 return pair ;
332 }
333
334 //==
335
336 GNet::DatagramSocket::DatagramSocket( int address_domain ) :
337 Socket( address_domain , SOCK_DGRAM , 0 )
338 {
339 }
340
341 GNet::DatagramSocket::~DatagramSocket()
342 {
343 }
344
345 void GNet::DatagramSocket::disconnect()
346 {
347 int rc = ::connect( m_socket.fd() , 0 , 0 ) ;
348 if( error(rc) )
349 saveReason() ;
350 }
351
352 GNet::Socket::ssize_type GNet::DatagramSocket::read( char * buf , size_type len )
353 {
354 if( len == 0 ) return 0 ;
355 sockaddr sender ; // not used
356 socklen_t sender_len = sizeof(sender) ;
357 ssize_type nread = G::Msg::recvfrom( m_socket.fd() , buf , len , 0 , &sender , &sender_len ) ;
358 if( sizeError(nread) )
359 {
360 saveReason() ;
361 return -1 ;
362 }
363 return nread ;
364 }
365
366 GNet::Socket::ssize_type GNet::DatagramSocket::readfrom( char * buf , size_type len , Address & src_address )
367 {
368 if( len == 0 ) return 0 ;
369 sockaddr sender ;
370 socklen_t sender_len = sizeof(sender) ;
371 ssize_type nread = G::Msg::recvfrom( m_socket.fd() , buf , len , 0 , &sender , &sender_len ) ;
372 if( sizeError(nread) )
373 {
374 saveReason() ;
375 return -1 ;
376 }
377 src_address = Address( &sender , sender_len ) ;
378 return nread ;
379 }
380
381 GNet::Socket::ssize_type GNet::DatagramSocket::writeto( const char * buf , size_type len , const Address & dst )
382 {
383 ssize_type nsent = G::Msg::sendto( m_socket.fd() , buf , len , MSG_NOSIGNAL , dst.address() , dst.length() ) ;
384 if( nsent < 0 )
385 {
386 saveReason() ;
387 G_DEBUG( "GNet::DatagramSocket::write: write error " << m_reason ) ;
388 return -1 ;
389 }
390 return nsent ;
391 }
392
393 GNet::Socket::ssize_type GNet::DatagramSocket::write( const char * buf , size_type len )
394 {
395 return Socket::write( buf , len ) ;
396 }
397
398 void GNet::StreamSocket::setOptionsOnCreate( bool /*listener*/ )
399 {
400 if( G::Test::enabled("socket-linger-zero") )
401 setOptionLingerImp( 1 , 0 ) ;
402 else if( G::Test::enabled("socket-linger-default") )
403 ;
404 else
405 setOptionNoLinger() ;
406
407 if( G::Test::enabled("socket-keep-alive") )
408 setOptionKeepAlive() ;
409 }
410
411 void GNet::StreamSocket::setOptionsOnAccept()
412 {
413 if( G::Test::enabled("socket-linger-zero") )
414 setOptionLingerImp( 1 , 0 ) ;
415 else if( G::Test::enabled("socket-linger-default") )
416 ;
417 else
418 setOptionNoLinger() ;
419
420 if( G::Test::enabled("socket-keep-alive") )
421 setOptionKeepAlive() ;
422 }
423
424 void GNet::Socket::setOptionsOnConnect( bool ipv6 )
425 {
426 setOptionPureV6( ipv6 , NoThrow() ) ; // ignore errors - may fail if already bound
427 }
428
429 void GNet::Socket::setOptionsOnBind( bool ipv6 )
430 {
431 if( G::Test::enabled("socket-no-reuse") )
432 ;
433 else
434 setOptionReuse() ; // allow us to rebind another socket's (eg. time-wait zombie's) address
435
436 //setOptionExclusive() ; // don't allow anyone else to bind our address
437 setOptionPureV6( ipv6 ) ;
438 }
439
440 void GNet::Socket::setOptionKeepAlive()
441 {
442 setOption( SOL_SOCKET , "so_keepalive" , SO_KEEPALIVE , 1 ) ;
443 }
444
445 void GNet::Socket::setOptionNoLinger()
446 {
447 setOptionLingerImp( 0 , 0 ) ;
448 }
449
450 void GNet::Socket::setOptionLingerImp( int onoff , int time )
451 {
452 struct linger options ;
453 options.l_onoff = onoff ;
454 options.l_linger = time ;
455 bool ok = setOptionImp( SOL_SOCKET , SO_LINGER , reinterpret_cast<char*>(&options) , sizeof(options) ) ;
456 if( !ok )
457 {
458 saveReason() ;
459 throw SocketError( "cannot set no_linger" , m_reason_string ) ;
460 }
461 }
462
463 bool GNet::Socket::setOption( int level , const char * , int op , int arg , NoThrow )
464 {
465 const void * const vp = reinterpret_cast<const void*>(&arg) ;
466 bool ok = setOptionImp( level , op , vp , sizeof(int) ) ;
467 if( !ok )
468 saveReason() ;
469 return ok ;
470 }
471
472 void GNet::Socket::setOption( int level , const char * opp , int op , int arg )
473 {
474 if( !setOption( level , opp , op , arg , NoThrow() ) )
475 throw SocketError( opp , m_reason_string ) ;
476 }
477
478 /// \file gsocket.cpp
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::Address::family
Family family() const
Returns the address family.
Definition: gaddress_ipv4.cpp:189
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
gsleep.h
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::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::AddressStorage
A helper class for calling accept(), getsockname() and getpeername() and hiding the definition of soc...
Definition: gaddress.h:201
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
G::Msg::recv
static ssize_t recv(SOCKET, void *, size_t, int)
A recv() wrapper.
Definition: gmsg_unix.cpp:76
GNet::Socket
A network socket base class, holding a non-blocking socket file descriptor.
Definition: gsocket.h:49
GNet::AddressStorage::p2
socklen_t * p2()
Returns the length pointer for accept()/getsockname()/getpeername() to write into.
Definition: gaddress_ipv4.cpp:229
G::Msg::recvfrom
static ssize_t recvfrom(SOCKET, void *, size_t, int, sockaddr *, socklen_t *, int *fd_received_p=nullptr)
A recvfrom() replacement using recvmsg().
Definition: gmsg_unix.cpp:87
GNet::AddressStorage::p1
sockaddr * p1()
Returns the sockaddr pointer for accept()/getsockname()/getpeername() to write into.
Definition: gaddress_ipv4.cpp:224
GNet::EventLoop::dropRead
virtual void dropRead(Descriptor fd)=0
Removes the given event source descriptor from the list of read sources.
GNet::StreamSocket::StreamSocket
StreamSocket(int address_domain)
Constructor with a hint of the bind()/connect() address to be used later.
Definition: gsocket.cpp:268
G::Msg::send
static ssize_t send(SOCKET, const void *, size_t, int, int fd_to_send=-1)
A send() replacement using sendmsg().
Definition: gmsg_unix.cpp:32
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
gtest.h
GNet::Address::address
const sockaddr * address() const
Returns the sockaddr address.
Definition: gaddress_ipv4.cpp:154
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
G::Msg::sendto
static ssize_t sendto(SOCKET, const void *, size_t, int, const sockaddr *, socklen_t, int fd_to_send=-1)
A sendto() replacement using sendmsg().
Definition: gmsg_unix.cpp:38
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::EventLoop::addRead
virtual void addRead(Descriptor fd, EventHandler &, ExceptionHandler &)=0
Adds the given event source descriptor and associated handler to the read list.
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::AddressStorage::p
const sockaddr * p() const
Returns the pointer.
Definition: gaddress_ipv4.cpp:234
GNet::DatagramSocket::disconnect
void disconnect()
Releases the association between two datagram endpoints reversing the effect of the previous Socket::...
Definition: gsocket.cpp:345
GNet::EventLoop::addWrite
virtual void addWrite(Descriptor fd, EventHandler &, ExceptionHandler &)=0
Adds the given event source descriptor and associated handler to the write list.
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
gstr.h
gassert.h
G::Test::enabled
static bool enabled()
Returns true if test features are enabled.
Definition: gtest.cpp:69
GNet::StreamSocket::Listener
Overload discriminator class for GNet::StreamSocket.
Definition: gsocket.h:251
GNet::Address::length
socklen_t length() const
Returns the size of the sockaddr address. See address().
Definition: gaddress_ipv4.cpp:159
GNet::DatagramSocket::write
virtual ssize_type write(const char *buffer, size_type len) override
Override from Socket::write().
Definition: gsocket.cpp:393
GNet::Descriptor::valid
bool valid() const
Returns true if the socket part is valid, ignoring the handle.
Definition: gdescriptor_unix.cpp:30
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
GNet::Address::domain
int domain() const
Returns the address 'domain', eg. PF_INET.
Definition: gaddress_ipv4.cpp:184
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::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
gsocket.h
gmsg.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::NoThrow
Overload discriminator class for GNet::Socket.
Definition: gsocket.h:56
GNet::AddressStorage::n
socklen_t n() const
Returns the length.
Definition: gaddress_ipv4.cpp:239
GNet::EventLoop::dropOther
virtual void dropOther(Descriptor fd)=0
Removes the given event source descriptor from the list of exception sources.
GNet::EventLoop::dropWrite
virtual void dropWrite(Descriptor fd)=0
Removes the given event source descriptor from the list of write sources.
GNet::Address::displayString
std::string displayString() const
Returns a string which represents the transport address for debugging and diagnostics purposes...
Definition: gaddress_ipv4.cpp:129
GNet::EventLoop::addOther
virtual void addOther(Descriptor fd, EventHandler &, ExceptionHandler &)=0
Adds the given event source descriptor and associated handler to the exception list.
GNet::EventLoop::instance
static EventLoop & instance()
Returns a reference to an instance of the class, if any.
Definition: geventloop.cpp:42
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
gdebug.h