36     m_socket = 
Descriptor( ::socket( domain , type , protocol ) ) ;
 
   37     if( !m_socket.
valid() )
 
   40         throw SocketError( 
"cannot create socket" , m_reason_string ) ;
 
   52 void GNet::Socket::prepare()
 
   59         G_WARNING( 
"GNet::Socket::open: cannot make socket non-blocking (" << m_reason_string << 
")" ) ;
 
   75 void GNet::Socket::drop()
 
   79     dropExceptionHandler() ;
 
   82 void GNet::Socket::saveReason()
 
   85     m_reason_string = reasonStringImp( m_reason ) ;
 
   88 void GNet::Socket::saveReason()
 const 
   95     G_DEBUG( 
"Socket::bind: binding " << local_address.
displayString() << 
" on fd " << m_socket ) ;
 
   97     if( local_address.
domain() != m_domain )
 
   98         throw SocketBindError( 
"address family does not match the socket domain" ) ;
 
  102     setOptionPureV6( local_address.
family() == Address::Family::ipv6() ) ;
 
  104     int rc = ::bind( m_socket.fd() , local_address.
address() , local_address.
length() ) ;
 
  108         throw SocketBindError( local_address.
displayString() , m_reason_string ) ;
 
  114     G_DEBUG( 
"Socket::bind: binding " << local_address.
displayString() << 
" on fd " << m_socket ) ;
 
  115     if( local_address.
domain() != m_domain ) 
return false ;
 
  119     setOptionPureV6( local_address.
family() == Address::Family::ipv6() ) ;
 
  121     int rc = ::bind( m_socket.fd() , local_address.
address() , local_address.
length() ) ;
 
  127     G_DEBUG( 
"GNet::Socket::connect: connecting to " << address.
displayString() ) ;
 
  128     if( address.
domain() != m_domain )
 
  130         G_WARNING( 
"GNet::Socket::connect: cannot connect: address family does not match " 
  131             "the socket domain (" << address.
domain() << 
"," << m_domain << 
")" ) ;
 
  135     setOptionPureV6( address.
family() == Address::Family::ipv6() , 
NoThrow() ) ; 
 
  137     int rc = ::connect( m_socket.fd() , address.
address() , address.
length() ) ;
 
  147             G_DEBUG( 
"GNet::Socket::connect: connection in progress" ) ;
 
  148             if( done != 
nullptr ) *done = false ;
 
  152         G_DEBUG( 
"GNet::Socket::connect: synchronous connect failure: " << m_reason ) ;
 
  156     if( done != 
nullptr ) *done = true ;
 
  162     if( static_cast<ssize_type>(len) < 0 )
 
  163         G_WARNING( 
"GNet::Socket::write: too big" ) ; 
 
  165     ssize_type nsent = ::send( m_socket.fd() , buf , len , MSG_NOSIGNAL ) ; 
 
  166     if( sizeError(nsent) ) 
 
  169         G_DEBUG( 
"GNet::Socket::write: write error " << m_reason ) ;
 
  172     else if( nsent < 0 || static_cast<size_type>(nsent) < len )
 
  181     int rc = ::listen( m_socket.fd() , backlog ) ;
 
  185         throw SocketError( 
"cannot listen on socket" , m_reason_string ) ;
 
  189 std::pair<bool,GNet::Address> GNet::Socket::getAddress( 
bool local )
 const 
  195             ::getsockname( m_socket.fd() , address_storage.
p1() , address_storage.
p2() ) :
 
  196             ::getpeername( m_socket.fd() , address_storage.
p1() , address_storage.
p2() ) ;
 
  204     return std::pair<bool,Address>( true , Address(address_storage) ) ;
 
  209     return getAddress( 
true ) ;
 
  214     return getAddress( 
false ) ;
 
  219     return getPeerAddress().first ;
 
  224     G_DEBUG( 
"GNet::Socket::addReadHandler: fd " << m_socket ) ;
 
  235     G_DEBUG( 
"GNet::Socket::addWriteHandler: fd " << m_socket ) ;
 
  241     G_DEBUG( 
"GNet::Socket::addExceptionHandler: fd " << m_socket ) ;
 
  257     std::ostringstream ss ;
 
  264     std::ostringstream ss ;
 
  271     ::shutdown( m_socket.fd() , for_writing ? 1 : 0 ) ;
 
  276     return m_socket.fd() ;
 
  282     Socket( address_domain , SOCK_STREAM , 0 )
 
  284     setOptionNoLinger() ;
 
  285     setOptionKeepAlive() ;
 
  302     ssize_type nread = 
G::Msg::recv( m_socket.fd() , buf , len , 0 ) ;
 
  303     if( sizeError(nread) )
 
  306         G_DEBUG( 
"GNet::StreamSocket::read: cannot read from " << m_socket.fd() ) ;
 
  320     Descriptor new_socket( ::accept(m_socket.fd(),addr.
p1(),addr.
p2()) ) ;
 
  321     if( ! new_socket.
valid() )
 
  324         throw SocketError( 
"cannot accept on socket" , m_reason_string ) ;
 
  328         throw SocketError( 
"testing" ) ;
 
  331     pair.second = 
Address( addr.
p() , addr.
n() ) ;
 
  332     G_DEBUG( 
"GNet::StreamSocket::accept: accepted from socket " << m_socket.fd() 
 
  333         << 
" onto socket " << new_socket << 
" with address " << pair.second.
displayString() ) ;
 
  335     pair.first.get()->setOptionNoLinger() ;
 
  342     Socket( address_domain , SOCK_DGRAM , 0 )
 
  352     int rc = ::connect( m_socket.fd() , 0 , 0 ) ;
 
  359     if( len == 0 ) 
return 0 ;
 
  361     socklen_t sender_len = 
sizeof(sender) ;
 
  362     ssize_type nread = 
G::Msg::recvfrom( m_socket.fd() , buf , len , 0 , &sender , &sender_len ) ;
 
  363     if( sizeError(nread) )
 
  373     if( len == 0 ) 
return 0 ;
 
  375     socklen_t sender_len = 
sizeof(sender) ;
 
  376     ssize_type nread = 
G::Msg::recvfrom( m_socket.fd() , buf , len , 0 , &sender , &sender_len ) ;
 
  377     if( sizeError(nread) )
 
  382     src_address = 
Address( &sender , sender_len ) ;
 
  388     G_DEBUG( 
"GNet::DatagramSocket::write: sending " << len << 
" bytes to " << dst.
displayString() ) ;
 
  394         G_DEBUG( 
"GNet::DatagramSocket::write: write error " << m_reason ) ;
 
  405 void GNet::Socket::setOptionKeepAlive()
 
  407     setOption( SOL_SOCKET , 
"so_keepalive" , SO_KEEPALIVE , 1 ) ;
 
  410 void GNet::Socket::setOptionNoLinger()
 
  412     struct linger options ;
 
  413     options.l_onoff = 0 ;
 
  414     options.l_linger = 0 ;
 
  415     bool ok = setOptionImp( SOL_SOCKET , SO_LINGER , reinterpret_cast<char*>(&options) , 
sizeof(options) ) ;
 
  419         throw SocketError( 
"cannot set so_linger" , m_reason_string ) ;
 
  423 bool GNet::Socket::setOption( 
int level , 
const char * , 
int op , 
int arg , NoThrow )
 
  425     const void * 
const vp = 
reinterpret_cast<const void*
>(&arg) ;
 
  426     bool ok = setOptionImp( level , op , vp , 
sizeof(
int) ) ;
 
  432 void GNet::Socket::setOption( 
int level , 
const char * opp , 
int op , 
int arg )
 
  434     if( !setOption( level , opp , op , arg , NoThrow() ) )
 
  435         throw SocketError( opp , m_reason_string ) ;
 
Family family() const 
Returns the address family. 
 
virtual ssize_type read(char *buffer, size_type len)
Override from Socket::read(). 
 
std::pair< bool, Address > getLocalAddress() const 
Retrieves local address of the socket. 
 
void listen(int backlog=1)
Starts the socket listening on the bound address for incoming connections or incoming datagrams...
 
virtual void addWrite(Descriptor fd, EventHandler &handler)=0
Adds the given event source descriptor and associated handler to the write list. 
 
bool connect(const Address &addr, bool *done=nullptr)
Initiates a connection to (or association with) the given address. 
 
void dropReadHandler()
Reverses addReadHandler(). 
 
void addExceptionHandler(EventHandler &handler)
Adds this socket to the event source list so that the given handler receives exception events...
 
void addWriteHandler(EventHandler &handler)
Adds this socket to the event source list so that the given handler receives write events when flow c...
 
virtual ~DatagramSocket()
Destructor. 
 
and hiding the definition of sockaddr_storage. 
 
The GNet::Address class encapsulates a TCP/UDP transport address. 
 
The Socket class encapsulates a non-blocking Unix socket file descriptor or a Windows 'SOCKET' handle...
 
socklen_t * p2()
Returns the length pointer for accept()/getsockname()/getpeername() to write into. 
 
void addReadHandler(EventHandler &handler)
Adds this socket to the event source list so that the given handler receives read events...
 
sockaddr * p1()
Returns the sockaddr pointer for accept()/getsockname()/getpeername() to write into. 
 
virtual void dropRead(Descriptor fd)=0
Removes the given event source descriptor from the list of read sources. 
 
StreamSocket(int address_domain)
Constructor with a hint of the bind()/connect() address to be used later. 
 
virtual SOCKET fd() const 
Returns the socket descriptor. Override from G::ReadWrite. 
 
virtual ~StreamSocket()
Destructor. 
 
A class that encapsulates a network file descriptor and hides knowledge of its o/s-spefific error val...
 
const sockaddr * address() const 
Returns the sockaddr address. 
 
static ssize_t sendto(int, const void *, size_t, int, const sockaddr *, socklen_t, int fd_to_send=-1)
A sendto() replacement using sendmsg(). 
 
ssize_type writeto(const char *buffer, size_type len, const Address &dst)
Sends a datagram to the given address. 
 
DatagramSocket(int address_domain)
Constructor with a hint of a local address. 
 
void dropExceptionHandler()
Reverses addExceptionHandler(). 
 
virtual void dropException(Descriptor fd)=0
Removes the given event source descriptor from the list of exception sources. 
 
void dropWriteHandler()
Reverses addWriteHandler(). 
 
void bind(const Address &)
Binds the socket with the given address. 
 
const sockaddr * p() const 
Returns the pointer. 
 
std::string reasonString() const 
Returns the failure reason as a string. 
 
void disconnect()
Releases the association between two datagram endpoints reversing the effect of the previous Socket::...
 
std::pair< bool, Address > getPeerAddress() const 
Retrieves address of socket's peer. 
 
A derivation of GNet::Socket for a stream socket. 
 
virtual void addRead(Descriptor fd, EventHandler &handler)=0
Adds the given event source descriptor and associated handler to the read list. 
 
static Address defaultAddress()
Returns a default address, being the IPv4 wildcard address with a zero port number. 
 
static bool enabled()
Returns true if test features are enabled. 
 
socklen_t length() const 
Returns the size of the sockaddr address. See address(). 
 
bool valid() const 
Returns true if the descriptor is valid. 
 
virtual ~Socket()
Destructor. 
 
Socket(int domain, int type, int protocol)
Constructor used by derived classes. 
 
virtual void addException(Descriptor fd, EventHandler &handler)=0
Adds the given event source descriptor and associated handler to the exception list. 
 
A class which is used to return a new()ed socket to calling code, together with associated informatio...
 
static ssize_t recvfrom(int, void *, size_t, int, sockaddr *, socklen_t *, int *fd_received_p=nullptr)
A recvfrom() replacement using recvmsg(). 
 
int domain() const 
Returns the address 'domain', eg. PF_INET. 
 
A base class for classes that handle asynchronous events from the event loop. 
 
virtual ssize_type write(const char *buf, size_type len) override=0
Writes to the socket. 
 
bool hasPeer() const 
Returns true if the socket has a valid peer. 
 
virtual ssize_type read(char *buffer, size_type buffer_length)
Override from Socket::read(). 
 
virtual ssize_type write(const char *buf, size_type len)
Override from Socket::write(). 
 
static void init()
An optional early-initialisation function. May be called more than once. 
 
void shutdown(bool for_writing=true)
Shuts the socket for writing (or reading). 
 
AcceptPair accept()
Accepts an incoming connection, returning a new()ed socket and the peer address. 
 
Overload discriminator class for GNet::Socket. 
 
socklen_t n() const 
Returns the length. 
 
virtual ssize_type write(const char *buffer, size_type len)
Override from Socket::write(). 
 
virtual void dropWrite(Descriptor fd)=0
Removes the given event source descriptor from the list of write sources. 
 
std::string displayString() const 
Returns a string which represents the transport address for debugging and diagnostics purposes...
 
static EventLoop & instance()
Returns a reference to an instance of the class, if any. 
 
ssize_type readfrom(char *buffer, size_type len, Address &src)
Reads a datagram and returns the sender's address by reference. 
 
std::string asString() const 
Returns the socket handle as a string. 
 
static ssize_t recv(int, void *, size_t, int, int *fd_received_p=nullptr)
A recv() replacement using recvmsg().