42 G_DEBUG(
"GNet::Socket::open: cannot open a socket (" <<
m_reason <<
")" ) ;
61 G_WARNING(
"GNet::Socket::open: cannot make socket non-blocking (" << m_reason <<
")" ) ;
77 if( valid() ) doClose() ;
85 void GNet::Socket::drop()
89 dropExceptionHandler() ;
94 return valid( m_socket ) ;
107 int rc = ::bind( m_socket.fd(), local_address.
address() , local_address.
length() ) ;
110 m_reason = reason() ;
114 const bool debug = true ;
117 std::pair<bool,Address> pair = getLocalAddress() ;
120 G_WARNING(
"GNet::Socket::bind: cannot get bound address" ) ;
124 G_DEBUG(
"GNet::Socket::bind: bound " << pair.second.displayString() <<
" on fd " << m_socket ) ;
136 int rc = ::connect( m_socket.fd(), address.
address(), address.
length() ) ;
139 m_reason = reason() ;
146 G_DEBUG(
"GNet::Socket::connect: connection in progress" ) ;
147 if( done != NULL ) *done = false ;
151 G_DEBUG(
"GNet::Socket::connect: synchronous connect failure: " << m_reason ) ;
155 if( done != NULL ) *done = true ;
161 if( static_cast<ssize_type>(len) < 0 )
162 G_WARNING(
"GNet::Socket::write: too big" ) ;
164 ssize_type nsent = ::send( m_socket.fd() , buf , len , 0 ) ;
166 if( sizeError(nsent) )
168 m_reason = reason() ;
169 G_DEBUG(
"GNet::Socket::write: write error " << m_reason ) ;
172 else if( nsent < 0 || static_cast<size_type>(nsent) < len )
174 m_reason = reason() ;
181 struct linger options ;
182 options.l_onoff = 0 ;
183 options.l_linger = 0 ;
184 socklen_t sizeof_options =
sizeof(options) ;
185 G_IGNORE_RETURN(
int) ::setsockopt( m_socket.fd() , SOL_SOCKET ,
186 SO_LINGER ,
reinterpret_cast<char*
>(&options) , sizeof_options ) ;
192 G_IGNORE_RETURN(
int) ::setsockopt( m_socket.fd() , SOL_SOCKET ,
193 SO_KEEPALIVE ,
reinterpret_cast<char*
>(&keep_alive) ,
sizeof(keep_alive) ) ;
199 G_IGNORE_RETURN(
int) ::setsockopt( m_socket.fd() , SOL_SOCKET ,
200 SO_REUSEADDR ,
reinterpret_cast<char*
>(&on) ,
sizeof(on) ) ;
205 int rc = ::listen( m_socket.fd() , backlog ) ;
208 m_reason = reason() ;
224 ::getsockname( m_socket.fd() , address_storage.
p1() , address_storage.
p2() ) :
225 ::getpeername( m_socket.fd() , address_storage.
p1() , address_storage.
p2() ) ;
229 const_cast<Socket*
>(
this)->m_reason = reason() ;
233 return std::pair<bool,Address>( true ,
Address(address_storage) ) ;
238 return getAddress(
true ) ;
243 return getAddress(
false ) ;
248 return getPeerAddress().first ;
254 G_DEBUG(
"GNet::Socket::addReadHandler: fd " << m_socket ) ;
266 G_DEBUG(
"GNet::Socket::addWriteHandler: fd " << m_socket ) ;
273 G_DEBUG(
"GNet::Socket::addExceptionHandler: fd " << m_socket ) ;
289 std::ostringstream ss ;
296 std::ostringstream ss ;
303 ::shutdown( m_socket.fd() , for_writing ? 1 : 0 ) ;
308 return static_cast<int>( m_socket.fd() ) ;
321 Socket( address_hint.domain() , SOCK_STREAM , 0 )
338 if( len == 0 )
return 0 ;
340 ssize_type nread = ::recv( m_socket.fd() , buf , len , 0 ) ;
341 if( sizeError(nread) )
343 m_reason = reason() ;
344 G_DEBUG(
"GNet::StreamSocket::read: fd " << m_socket <<
": read error " << m_reason ) ;
349 G_DEBUG(
"GNet::StreamSocket::read: fd " << m_socket <<
": read zero bytes" ) ;
359 socklen_t addr_length =
sizeof(addr) ;
360 Descriptor new_socket( ::accept( m_socket.fd() , &addr, &addr_length ) ) ;
361 if( valid(new_socket) )
366 pair.
first.get()->setNoLinger() ;
370 m_reason = reason() ;
371 G_DEBUG(
"GNet::StreamSocket::accept: failure" ) ;
384 Socket( address_hint.domain() , SOCK_DGRAM , 0 )
394 int rc = ::connect( m_socket.fd() , 0 , 0 ) ;
396 m_reason = reason() ;
402 socklen_t sender_len =
sizeof(sender) ;
403 ssize_type nread = ::recvfrom( m_socket.fd() ,
reinterpret_cast<char*
>(buf) , len , 0 , &sender , &sender_len ) ;
404 if( sizeError(nread) )
406 m_reason = reason() ;
410 src_address =
Address( &sender , sender_len ) ;
416 G_DEBUG(
"GNet::DatagramSocket::write: sending " << len <<
" bytes to " << dst.
displayString() ) ;
421 m_reason = reason() ;
422 G_DEBUG(
"GNet::DatagramSocket::write: write error " << m_reason ) ;
ssize_type write(const char *buffer, size_type len, const Address &dst)
Sends a datagram to the given address.
DatagramSocket()
Default constructor.
bool listen(int backlog=1)
Starts the socket listening on the bound address for incoming connections or incoming datagrams...
std::pair< bool, Address > getLocalAddress() const
Retrieves local address of the socket.
virtual void addWrite(Descriptor fd, EventHandler &handler)=0
Adds the given event source descriptor and associated handler to the write list.
void dropReadHandler()
Reverses addReadHandler().
void addExceptionHandler(EventHandler &handler)
Adds this socket to the event source list so that the given handler receives exception events...
bool connect(const Address &addr, bool *done=NULL)
Initiates a connection to (or association with) the given address.
virtual ssize_type write(const char *buf, size_type len)
Sends data.
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.
std::pair< bool, Address > getAddress(bool) const
A helper class for calling getsockname() and getpeername() and hiding the definition of sockaddr_stor...
The Address class encapsulates an IP 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 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 getsockname()/getpeername() to write into.
virtual void dropRead(Descriptor fd)=0
Removes the given event source descriptor from the list of read sources.
static Address invalidAddress()
Returns an invalid address.
virtual ~StreamSocket()
Destructor.
A network file descriptor.
const sockaddr * address() const
Returns the sockaddr address.
StreamSocket()
Default constructor. Check with valid().
bool bind(const Address &address)
Binds the socket with an INADDR_ANY network address and the port number taken from the given address...
int fd(Credentials) const
Returns the socket descriptor as an integer.
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().
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 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.
std::string displayString(bool with_port=true, bool with_scope_id=false) const
Returns a string which represents the address for debugging and diagnostics purposes.
ssize_type read(void *buffer, size_type len, Address &src)
Reads a datagram and returns the sender's address by reference.
static bool enabled()
Returns true if test features are enabled.
socklen_t length() const
Returns the size of the sockaddr address.
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...
A base class for classes that handle asynchronous socket events.
bool hasPeer() const
Returns true if the socket has a valid peer.
ssize_type read(char *buffer, size_type buffer_length)
Reads data from the socket stream.
static void init()
An optional early-initialisation function.
bool valid() const
Returns true if the socket handle is valid (open).
A credentials class that allows SocketProtocol to call Socket::fd().
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.
virtual void dropWrite(Descriptor fd)=0
Removes the given event source descriptor from the list of write sources.
static EventLoop & instance()
Returns a reference to an instance of the class, if any.
std::string asString() const
Returns the socket handle as a string.