You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2010/04/10 00:17:38 UTC
svn commit: r932637 [2/3] - in
/activemq/activemq-cpp/trunk/activemq-cpp/src: main/
main/activemq/transport/tcp/ main/decaf/internal/net/tcp/ main/decaf/net/
test/decaf/net/
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.cpp?rev=932637&r1=932636&r2=932637&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.cpp Fri Apr 9 22:17:38 2010
@@ -16,139 +16,365 @@
*/
#include "ServerSocket.h"
-#include "SocketError.h"
+
+#include <decaf/net/SocketImpl.h>
+#include <decaf/net/Socket.h>
+#include <decaf/net/SocketOptions.h>
#include <decaf/internal/net/tcp/TcpSocket.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <assert.h>
-#include <string>
+#include <memory>
using namespace decaf;
+using namespace decaf::io;
using namespace decaf::net;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+using namespace decaf::internal;
+using namespace decaf::internal::net;
using namespace decaf::internal::net::tcp;
////////////////////////////////////////////////////////////////////////////////
-ServerSocket::ServerSocket() {
- socketHandle = NULL;
+SocketImplFactory* ServerSocket::factory = NULL;
+
+////////////////////////////////////////////////////////////////////////////////
+ServerSocket::ServerSocket() : impl(NULL), created(false), closed(false), bound(false) {
+
+ this->impl = this->factory != NULL ? factory->createSocketImpl() : new TcpSocket();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ServerSocket::ServerSocket( int port )
+ throw( decaf::io::IOException, decaf::lang::exceptions::IllegalArgumentException ) :
+ impl(NULL), created(false), closed(false), bound(false) {
+
+ this->impl = this->factory != NULL ? factory->createSocketImpl() : new TcpSocket();
+
+ if( port < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Port value was invalid: %d", port );
+ }
+
+ this->setupSocketImpl( "", port, getDefaultBacklog() );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ServerSocket::ServerSocket( int port, int backlog )
+ throw( decaf::io::IOException, decaf::lang::exceptions::IllegalArgumentException ) :
+ impl(NULL), created(false), closed(false), bound(false) {
+
+ this->impl = this->factory != NULL ? factory->createSocketImpl() : new TcpSocket();
+
+ if( port < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Port value was invalid: %d", port );
+ }
+
+ this->setupSocketImpl( "", port, backlog );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ServerSocket::ServerSocket( const std::string& ipAddress, int port, int backlog )
+ throw( decaf::io::IOException, decaf::lang::exceptions::IllegalArgumentException ) :
+ impl(NULL), created(false), closed(false), bound(false) {
+
+ this->impl = this->factory != NULL ? factory->createSocketImpl() : new TcpSocket();
+
+ if( port < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Port value was invalid: %d", port );
+ }
+
+ this->setupSocketImpl( ipAddress, port, backlog );
}
////////////////////////////////////////////////////////////////////////////////
ServerSocket::~ServerSocket() {
- // No shutdown, just close - dont want blocking destructor.
- close();
+ try{
+ close();
+
+ delete this->impl;
+ }
+ DECAF_CATCH_NOTHROW( Exception )
+ DECAF_CATCHALL_NOTHROW()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ServerSocket::setupSocketImpl( const std::string ipAddress, int port, int backlog ) {
+
+ try{
+
+ this->impl->create();
+ this->created = true;
+
+ try {
+ this->impl->bind( ipAddress, port );
+ this->bound = true;
+ this->impl->listen( backlog > 0 ? backlog : getDefaultBacklog() );
+ } catch( IOException& ex ) {
+ close();
+ throw ex;
+ }
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
}
////////////////////////////////////////////////////////////////////////////////
-void ServerSocket::bind( const char* host, int port ) throw ( SocketException ) {
- this->bind( host, port, SOMAXCONN );
+void ServerSocket::bind( const std::string& host, int port )
+ throw( decaf::io::IOException, decaf::lang::exceptions::IllegalArgumentException ) {
+
+ try{
+ this->bind( host, port, getDefaultBacklog() );
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCHALL_THROW( IOException )
}
////////////////////////////////////////////////////////////////////////////////
-void ServerSocket::bind( const char* host,
- int port,
- int backlog ) throw ( SocketException ) {
+void ServerSocket::bind( const std::string& address, int port, int backlog )
+ throw( decaf::io::IOException, decaf::lang::exceptions::IllegalArgumentException ) {
- apr_status_t result = APR_SUCCESS;
+ checkClosed();
+
+ if( port < 0 || port > 65535 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Specified port value is out of range: %d", port );
+ }
if( isBound() ) {
- throw SocketException ( __FILE__, __LINE__,
- "ServerSocket::bind - Socket already bound" );
+ throw IOException(
+ __FILE__, __LINE__, "ServerSocket is already bound." );
}
- // Verify the port value.
- if( port <= 0 || port > 65535 ) {
- throw SocketException(
- __FILE__, __LINE__,
- "ServerSocket::bind - Port out of range: %d", port );
+ try{
+
+ ensureCreated();
+
+ try {
+ this->impl->bind( address, port );
+ this->bound = true;
+ this->impl->listen( backlog > 0 ? backlog : getDefaultBacklog() );
+ } catch( IOException& ex ) {
+ close();
+ throw ex;
+ }
}
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
- // Create the Address Info for the Socket
- result = apr_sockaddr_info_get(
- &socketAddress, host, APR_INET, (apr_port_t)port, 0, apr_pool.getAprPool() );
+////////////////////////////////////////////////////////////////////////////////
+void ServerSocket::close() throw ( decaf::io::IOException ){
- if( result != APR_SUCCESS ) {
- socketHandle = NULL;
- throw SocketException(
- __FILE__, __LINE__,
- SocketError::getErrorString().c_str() );
+ try{
+ if( !this->closed ) {
+ this->closed = true;
+ this->impl->close();
+ }
}
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
- // Create the socket.
- result = apr_socket_create(
- &socketHandle, APR_INET, SOCK_STREAM, APR_PROTO_TCP, apr_pool.getAprPool() );
+////////////////////////////////////////////////////////////////////////////////
+bool ServerSocket::isBound() const {
+ return this->bound;
+}
- if( result != APR_SUCCESS ) {
- socketHandle = NULL;
- throw SocketException(
- __FILE__, __LINE__,
- SocketError::getErrorString().c_str() );
+////////////////////////////////////////////////////////////////////////////////
+bool ServerSocket::isClosed() const {
+ return this->closed;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Socket* ServerSocket::accept() throw( decaf::io::IOException, decaf::net::SocketTimeoutException ) {
+
+ checkClosed();
+
+ if( !isBound() ) {
+ throw IOException(
+ __FILE__, __LINE__, "The ServerSocket has not yet been bound." );
}
- // Set the socket to reuse the address and default as blocking
- apr_socket_opt_set( socketHandle, APR_SO_REUSEADDR, 1 );
- apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, 0);
- apr_socket_timeout_set( socketHandle, -1 );
+ try{
+ ensureCreated();
+ std::auto_ptr<Socket> newSocket( new Socket() );
+ this->implAccept( newSocket.get() );
+ return newSocket.release();
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
- // Bind to the Socket, this may be where we find out if the port is in use.
- result = apr_socket_bind( socketHandle, socketAddress );
+////////////////////////////////////////////////////////////////////////////////
+void ServerSocket::implAccept( Socket* socket ) throw( decaf::io::IOException ) {
- if( result != APR_SUCCESS ) {
- close();
- throw SocketException(
- __FILE__, __LINE__,
- "ServerSocket::bind - %s",
- SocketError::getErrorString().c_str() );
+ try{
+ this->impl->accept( socket->impl );
+ socket->accepted();
}
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
- // Setup the listen for incoming connection requests
- result = apr_socket_listen( socketHandle, backlog );
+////////////////////////////////////////////////////////////////////////////////
+int ServerSocket::getReceiveBufferSize() const throw( SocketException ) {
- if( result != APR_SUCCESS ) {
- close();
- throw SocketException(
- __FILE__, __LINE__,
- "ServerSocket::bind - %s",
- SocketError::getErrorString().c_str() );
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_RCVBUF );
}
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
}
////////////////////////////////////////////////////////////////////////////////
-void ServerSocket::close() throw ( lang::Exception ){
+void ServerSocket::setReceiveBufferSize( int size )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException ) {
- if( isBound() ) {
- apr_socket_close( socketHandle );
- socketHandle = NULL;
+ checkClosed();
+
+ if( size <= 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Buffer size given was invalid: %d", size );
+ }
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_RCVBUF, size );
}
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
}
////////////////////////////////////////////////////////////////////////////////
-bool ServerSocket::isBound() const {
- return this->socketHandle != NULL;
+bool ServerSocket::getReuseAddress() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_REUSEADDR ) == 0 ? false : true;
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
}
////////////////////////////////////////////////////////////////////////////////
-Socket* ServerSocket::accept() throw (SocketException)
-{
- SocketHandle incoming = NULL;
- apr_status_t result = APR_SUCCESS;
+void ServerSocket::setReuseAddress( bool reuse ) throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_REUSEADDR, reuse ? 1 : 0 );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int ServerSocket::getSoTimeout() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_TIMEOUT );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ServerSocket::setSoTimeout( int timeout )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException ) {
+
+ checkClosed();
- // Loop to ignore any signal interruptions that occur during the operation.
- do {
- result = apr_socket_accept( &incoming, socketHandle, apr_pool.getAprPool() );
- } while( result == APR_EINTR );
+ if( timeout < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Socket timeout given was invalid: %d", timeout );
+ }
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_TIMEOUT, timeout );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
- if( result != APR_SUCCESS ) {
- std::cout << "Failed to accept New Connection:" << std::endl;
+////////////////////////////////////////////////////////////////////////////////
+void ServerSocket::setSocketImplFactory( SocketImplFactory* factory )
+ throw( decaf::io::IOException,
+ decaf::net::SocketException ) {
+
+ if( Socket::factory != NULL ) {
throw SocketException(
- __FILE__, __LINE__,
- "ServerSocket::accept - %s",
- SocketError::getErrorString().c_str() );
+ __FILE__, __LINE__, "A SocketInplFactory was already set." );
}
- return new TcpSocket( incoming );
+ Socket::factory = factory;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string ServerSocket::toString() const {
+
+ std::ostringstream str;
+
+ str << "ServerSocket[";
+
+ if( !isBound() ) {
+ str << "unbound]";
+ } else {
+
+ }
+
+ return str.str();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ServerSocket::checkClosed() const throw( decaf::io::IOException ) {
+ if( this->closed ) {
+ throw IOException( __FILE__, __LINE__, "ServerSocket already closed." );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ServerSocket::ensureCreated() const throw( decaf::io::IOException ) {
+
+ try{
+ if( !this->created ) {
+ this->impl->create();
+ this->created = true;
+ }
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int ServerSocket::getDefaultBacklog() {
+ return 50;
}
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.h?rev=932637&r1=932636&r2=932637&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ServerSocket.h Fri Apr 9 22:17:38 2010
@@ -14,66 +14,174 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#ifndef _DECAF_NET_SERVERSOCKETIMPL_H_
-#define _DECAF_NET_SERVERSOCKETIMPL_H_
+#ifndef _DECAF_NET_SERVERSOCKET_H_
+#define _DECAF_NET_SERVERSOCKET_H_
-#include <decaf/net/SocketException.h>
#include <decaf/util/Config.h>
-#include <decaf/internal/AprPool.h>
-#include <apr_network_io.h>
+#include <decaf/net/SocketImpl.h>
+#include <decaf/net/SocketImplFactory.h>
+
+#include <decaf/lang/exceptions/NullPointerException.h>
+#include <decaf/lang/exceptions/IllegalArgumentException.h>
+#include <decaf/net/UnknownHostException.h>
+#include <decaf/net/SocketTimeoutException.h>
+#include <decaf/io/IOException.h>
+
+#include <string>
namespace decaf{
namespace net{
class Socket;
+ class SocketImpl;
/**
- * A server socket class (for testing purposes).
+ * This class implements server sockets. A server socket waits for requests to come in over
+ * the network.
+ *
+ * The actual work of the server socket is performed by an instance of the SocketImpl class.
+ * An application can change the socket factory that creates the socket implementation to configure
+ * itself to create sockets of a particular type.
+ *
+ * @since 1.0
*/
class DECAF_API ServerSocket {
- public:
+ private:
- typedef apr_socket_t* SocketHandle;
- typedef apr_sockaddr_t* SocketAddress;
+ // Factory for creating sockets, if not set a Plan TCP Socket is created
+ static SocketImplFactory* factory;
- private:
+ // The actual Socket that this Socket represents.
+ mutable SocketImpl* impl;
+ mutable volatile bool created;
+
+ bool closed;
+ bool bound;
- SocketHandle socketHandle;
- SocketAddress socketAddress;
- decaf::internal::AprPool apr_pool;
+ int backlog;
+ int port;
public:
/**
- * Constructor.
* Creates a non-bound server socket.
*/
ServerSocket();
/**
- * Destructor.
+ * Creates a new ServerSocket bound to the specified port, if the value of port is 0, then
+ * any free port is chosen.
+ *
+ * When this constructor is called the size of the backlog queue is set at 50, connections
+ * that arrive after the backlog has been reached are refused.
+ *
+ * If a SocketImplFactory is registered then the createSocketImpl method on the factory
+ * will be called otherwise a default SocketImpl is created.
+ *
+ * @param port
+ * The port to bind the ServerSocket to.
+ *
+ * @throws IOException if there is an I/O error while performing this operation.
+ * @throws IllegalArgumentException if the port value is negative or greater than 65535.
+ */
+ ServerSocket( int port )
+ throw( decaf::io::IOException,
+ decaf::lang::exceptions::IllegalArgumentException );
+
+ /**
+ * Creates a new ServerSocket bound to the specified port, if the value of port is 0, then
+ * any free port is chosen.
+ *
+ * When this constructor is called the size of the backlog queue is set at backlog, connections
+ * that arrive after the backlog has been reached are refused. If backlog is zero or negative
+ * then the default backlog value of 50 is used.
+ *
+ * If a SocketImplFactory is registered then the createSocketImpl method on the factory
+ * will be called otherwise a default SocketImpl is created.
+ *
+ * @param port
+ * The port to bind the ServerSocket to.
+ * @param backlog
+ * The the number of incoming connection attempts to queue before connections are refused.
+ *
+ * @throws IOException if there is an I/O error while performing this operation.
+ * @throws IllegalArgumentException if the port value is negative or greater than 65535.
+ */
+ ServerSocket( int port, int backlog )
+ throw( decaf::io::IOException,
+ decaf::lang::exceptions::IllegalArgumentException );
+
+ /**
+ * Creates a new ServerSocket bound to the specified port, if the value of port is 0, then
+ * any free port is chosen. If the value of the ipAddress is empty then the ANY address is
+ * used.
+ *
+ * When this constructor is called the size of the backlog queue is set at backlog, connections
+ * that arrive after the backlog has been reached are refused. If backlog is zero or negative
+ * then the default backlog value of 50 is used.
+ *
+ * If a SocketImplFactory is registered then the createSocketImpl method on the factory
+ * will be called otherwise a default SocketImpl is created.
+ *
+ * @param ipAddress
+ * The IP Address to bind to on the local machine.
+ * @param port
+ * The port to bind the ServerSocket to.
+ * @param backlog
+ * The the number of incoming connection attempts to queue before connections are refused.
+ *
+ * @throws IOException if there is an I/O error while performing this operation.
+ * @throws IllegalArgumentException if the port value is negative or greater than 65535.
+ */
+ ServerSocket( const std::string& ipAddress, int port, int backlog )
+ throw( decaf::io::IOException,
+ decaf::lang::exceptions::IllegalArgumentException );
+
+ /**
* Releases socket handle if close() hasn't been called.
*/
virtual ~ServerSocket();
+ protected:
+
+ /**
+ * Creates a ServerSocket wrapping the provided SocketImpl instance, this Socket is
+ * considered unconnected. The ServerSocket class takes ownership of this SocketImpl
+ * pointer and will delete it when the Socket class is destroyed.
+ *
+ * @param impl
+ * The SocketImpl instance to wrap.
+ *
+ * @throws NullPointerException if the passed SocketImpl is Null.
+ */
+ ServerSocket( SocketImpl* impl );
+
public:
/**
- * Bind and listen to given IP/dns and port.
+ * Bind and listen to given local IPAddress and port, if the address is empty
+ * than a valid local address will be chosen, and if the port of 0 than an
+ * available open port will be chosen.
*
* @param host
* The IP address or host name.
* @param port
* The TCP port between 1..655535.
*
- * @throws SocketException if an I/O error occurs while binding the socket.
+ * @throws IOException if an I/O error occurs while binding the socket.
+ * @throws IllegalArgumentException if the parameters are not valid.
*/
- virtual void bind( const char* host, int port )
- throw ( SocketException );
+ void bind( const std::string& host, int port )
+ throw ( decaf::io::IOException, decaf::lang::exceptions::IllegalArgumentException );
/**
- * Bind and listen to given IP/dns and port.
+ * Bind and listen to given local IPAddress and port, if the address is empty
+ * than a valid local address will be chosen, and if the port of 0 than an
+ * available open port will be chosen.
+ *
+ * If the backlog is greater than zero it will be used instead of the default
+ * value, otherwise the default value is used and no error is generated.
*
* @param host
* The IP address or host name.
@@ -82,28 +190,169 @@ namespace net{
* @param backlog
* The size of listen backlog.
*
- * @throws SocketException if an I/O error occurs while binding the socket.
+ * @throws IOException if an I/O error occurs while binding the socket.
+ * @throws IllegalArgumentException if the parameters are not valid.
*/
- virtual void bind( const char* host, int port, int backlog )
- throw ( SocketException );
+ void bind( const std::string& host, int port, int backlog )
+ throw ( decaf::io::IOException, decaf::lang::exceptions::IllegalArgumentException );
/**
- * Blocks until a client connects to the bound socket.
- * @return new socket. Never returns NULL.
+ * Listens for a connection request on the bound IPAddress and Port for this ServerSocket, the
+ * caller blocks until a connection is made. If the SO_TIMEOUT option is set this method could
+ * throw a SocketTimeoutException if the operation times out.
+ *
+ * @return a new Socket object pointer. Never returns NULL, the returned pointer is owned by
+ * the caller and must be explicitly freed by them.
+ *
+ * @throws IOException if an I/O error occurs while binding the socket.
+ * @throws SocketTimeoutException if the SO_TIMEOUT option was used and the accept timed out.
*/
- virtual Socket* accept () throw ( SocketException );
+ Socket* accept()
+ throw( decaf::io::IOException, decaf::net::SocketTimeoutException );
/**
- * Closes the server socket.
+ * Closes the server socket, causing any Threads blocked on an accept call to
+ * throw an Exception.
+ *
+ * @throws IOException if an I/O error occurs while performing this operation.
*/
- virtual void close() throw( lang::Exception );
+ void close() throw( decaf::io::IOException );
+
+ /**
+ * @returns true if the close method has been called on the ServerSocket.
+ */
+ bool isClosed() const;
/**
* @return true of the server socket is bound.
*/
- virtual bool isBound() const;
+ bool isBound() const;
+
+ /**
+ * Gets the receive buffer size for this socket, SO_RCVBUF. This is the buffer used
+ * by the underlying platform socket to buffer received data.
+ *
+ * @return the receive buffer size in bytes.
+ *
+ * @throws SocketException if the operation fails.
+ */
+ int getReceiveBufferSize() const throw( SocketException );
+
+ /**
+ * Sets the receive buffer size for this socket, SO_RCVBUF.
+ *
+ * @param size
+ * Number of bytes to set the receive buffer to.
+ *
+ * @throws SocketException if the operation fails.
+ * @throws IllegalArgumentException if the value is zero or negative.
+ */
+ void setReceiveBufferSize( int size )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException );
+
+ /**
+ * Gets the reuse address flag, SO_REUSEADDR.
+ *
+ * @return True if the address can be reused.
+ *
+ * @throws SocketException if the operation fails.
+ */
+ bool getReuseAddress() const throw( SocketException );
+
+ /**
+ * Sets the reuse address flag, SO_REUSEADDR.
+ *
+ * @param reuse
+ * If true, sets the flag.
+ *
+ * @throws SocketException if the operation fails.
+ */
+ void setReuseAddress( bool reuse ) throw( SocketException );
+
+ /**
+ * Gets the timeout for socket operations, SO_TIMEOUT.
+ *
+ * @return The timeout in milliseconds for socket operations.
+ *
+ * @throws SocketException Thrown if unable to retrieve the information.
+ */
+ int getSoTimeout() const throw( SocketException );
+
+ /**
+ * Sets the timeout for socket operations, SO_TIMEOUT. A value of zero indicates that timeout
+ * is infinite for operations on this socket.
+ *
+ * @param timeout
+ * The timeout in milliseconds for socket operations.
+ *
+ * @throws SocketException Thrown if unable to set the information.
+ * @throws IllegalArgumentException if the timeout value is negative.
+ */
+ void setSoTimeout( int timeout )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException );
+
+ /**
+ * Gets the port number on the Local machine that this ServerSocket is bound to.
+ *
+ * @returns the port number of this machine that is bound, if not bound returns -1.
+ */
+ int getLocalPort() const;
+
+ /**
+ * @returns a string representing this ServerSocket.
+ */
+ std::string toString() const;
+
+ public:
+
+ /**
+ * Sets the instance of a SocketImplFactory that the ServerSocket class should use when new
+ * instances of this class are created. This method is only allowed to be used once
+ * during the lifetime of the application.
+ *
+ * @param factory
+ * The instance of a SocketImplFactory to use when new SocketImpl objects are created.
+ *
+ * @throws IOException if an I/O error occurs while performing this operation.
+ * @throws SocketException if this method has already been called with a valid factory.
+ */
+ static void setSocketImplFactory( SocketImplFactory* factory )
+ throw( decaf::io::IOException,
+ decaf::net::SocketException );
+
+ protected:
+
+ /**
+ * Virtual method that allows a ServerSocket subclass to override the accept call and
+ * provide its own SocketImpl for the socket.
+ *
+ * @param socket
+ * The socket object whose SocketImpl should be used for the accept call.
+ *
+ * @throws IOException if an I/O error occurs while performing this operation.
+ */
+ virtual void implAccept( Socket* socket )
+ throw( decaf::io::IOException );
+
+ /**
+ * Allows a subclass to override what is considered the default backlog.
+ *
+ * @returns the default backlog for connections.
+ */
+ virtual int getDefaultBacklog();
+
+ protected:
+
+ // Check for already closed and throw an error if so.
+ void checkClosed() const throw( decaf::io::IOException );
+
+ // Create but don't connect the underlying OS Socket instance, if not already created.
+ void ensureCreated() const throw( decaf::io::IOException );
+
+ // Binds and sets up the Listen for this Server Socket
+ void setupSocketImpl( const std::string ipAddress, int port, int backlog );
- };
+ };
}}
Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp?rev=932637&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp Fri Apr 9 22:17:38 2010
@@ -0,0 +1,686 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Socket.h"
+
+#include <decaf/net/SocketImpl.h>
+#include <decaf/net/SocketImplFactory.h>
+
+#include <decaf/internal/net/tcp/TcpSocket.h>
+
+using namespace decaf;
+using namespace decaf::net;
+using namespace decaf::io;
+using namespace decaf::internal;
+using namespace decaf::internal::net;
+using namespace decaf::internal::net::tcp;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+SocketImplFactory* Socket::factory = NULL;
+
+////////////////////////////////////////////////////////////////////////////////
+Socket::Socket() : impl(NULL), created(false), connected(false), closed(false),
+ bound(false), inputShutdown(false), outputShutdown(false) {
+
+ if( this->factory != NULL ) {
+ this->impl = factory->createSocketImpl();
+ return;
+ }
+
+ this->impl = new TcpSocket();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Socket::Socket( SocketImpl* impl ) : impl(impl), created(false), connected(false), closed(false),
+ bound(false), inputShutdown(false), outputShutdown(false) {
+
+ if( impl == NULL ) {
+ throw NullPointerException(
+ __FILE__, __LINE__, "SocketImpl pointer passed was Null." );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Socket::Socket( const std::string& host, int port ) : impl(NULL), created(false), connected(false),
+ closed(false), bound(false),
+ inputShutdown(false), outputShutdown(false){
+
+ if( port < 0 || port > 65535 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Port specified is out of range: %d", port );
+ }
+
+ try{
+
+ if( this->factory != NULL ) {
+ this->impl = factory->createSocketImpl();
+ } else {
+ this->impl = new TcpSocket();
+ }
+
+ this->initSocketImpl( host, port, "", 0 );
+ }
+ DECAF_CATCH_RETHROW( UnknownHostException )
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Socket::Socket( const std::string& host, int port, const std::string& localAddress, int localPort ) :
+ impl(NULL), created(false), connected(false), closed(false), bound(false),
+ inputShutdown(false), outputShutdown(false) {
+
+ if( port < 0 || port > 65535 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Port specified is out of range: %d", port );
+ }
+
+ try{
+
+ if( this->factory != NULL ) {
+ this->impl = factory->createSocketImpl();
+ } else {
+ this->impl = new TcpSocket();
+ }
+
+ this->initSocketImpl( host, port, localAddress, localPort );
+ }
+ DECAF_CATCH_RETHROW( UnknownHostException )
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Socket::~Socket() {
+ try{
+ close();
+ delete this->impl;
+ }
+ DECAF_CATCH_NOTHROW( Exception )
+ DECAF_CATCHALL_NOTHROW()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::initSocketImpl( const std::string& host, int port, const std::string& localAddress, int localPort )
+ throw( decaf::io::IOException, decaf::net::UnknownHostException ) {
+
+ try{
+
+ ensureCreated();
+
+ try {
+ this->impl->bind( localAddress, localPort );
+ this->bound = true;
+ this->impl->connect( host, port, 0 );
+ this->connected = true;
+ } catch( IOException& ex ) {
+ this->impl->close();
+ throw ex;
+ }
+ }
+ DECAF_CATCH_RETHROW( UnknownHostException )
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Socket::getPort() const {
+ return this->connected ? this->impl->getPort() : 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Socket::getLocalPort() const {
+ return this->bound ? this->impl->getLocalPort() : -1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string Socket::getInetAddress() const {
+ return this->connected ? this->impl->getInetAddress() : "";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string Socket::getLocalAddress() const {
+ return this->bound ? this->impl->getLocalAddress() : "0.0.0.0";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::bind( const std::string& ipaddress, int port )
+ throw( decaf::io::IOException, decaf::lang::exceptions::IllegalArgumentException ) {
+
+ checkClosed();
+
+ if( isBound() ) {
+ throw IOException(
+ __FILE__, __LINE__, "The Socket is already bound." );
+ }
+
+ try{
+
+ ensureCreated();
+
+ try {
+ this->impl->bind( ipaddress, port );
+ this->bound = true;
+ } catch( IOException& e ) {
+ this->impl->close();
+ throw e;
+ }
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::close() throw( decaf::io::IOException ) {
+ try{
+ this->closed = true;
+ this->impl->close();
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::connect( const std::string& host, int port )
+ throw( decaf::io::IOException,
+ decaf::lang::exceptions::IllegalArgumentException ) {
+
+ if( port < 0 || port > 65535 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Port specified is out of range: %d", port );
+ }
+
+ try{
+ this->connect( host, port, 0 );
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::connect( const std::string& host, int port, int timeout )
+ throw( decaf::io::IOException,
+ decaf::net::SocketTimeoutException,
+ decaf::lang::exceptions::IllegalArgumentException ) {
+
+ checkClosed();
+
+ if( timeout < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Timeout value specified is invalid: %d", timeout );
+ }
+
+ if( isConnected() ) {
+ throw SocketException(
+ __FILE__, __LINE__, "The Socket is already connected." );
+ }
+
+ if( host.empty() ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Host cannot be empty." );
+ }
+
+ try{
+
+ ensureCreated();
+
+ try {
+
+ if( !isBound() ) {
+ this->impl->bind( "", 0 );
+ this->bound = true;
+ }
+
+ this->impl->connect( host, port, timeout );
+ this->connected = true;
+
+ } catch( IOException& ex ) {
+ this->impl->close();
+ throw ex;
+ }
+ }
+ DECAF_CATCH_RETHROW( SocketTimeoutException )
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+InputStream* Socket::getInputStream() throw( decaf::io::IOException ) {
+
+ checkClosed();
+
+ try{
+
+ if( isInputShutdown() ) {
+ throw IOException( __FILE__, __LINE__, "Input was shutdown on this Socket." );
+ }
+
+ return this->impl->getInputStream();
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+OutputStream* Socket::getOutputStream() throw( decaf::io::IOException ) {
+
+ checkClosed();
+
+ try{
+
+ if( isOutputShutdown() ) {
+ throw IOException( __FILE__, __LINE__, "Output was shutdown on this Socket." );
+ }
+
+ return this->impl->getOutputStream();
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::shutdownInput() throw( decaf::io::IOException ) {
+
+ if( isInputShutdown() ) {
+ throw IOException( __FILE__, __LINE__, "Socket input has already been shutdown." );
+ }
+
+ checkClosed();
+
+ try{
+ this->impl->shutdownInput();
+ this->inputShutdown = true;
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::shutdownOutput() throw( decaf::io::IOException ) {
+
+ if( isOutputShutdown() ) {
+ throw IOException( __FILE__, __LINE__, "Socket output has already been shutdown." );
+ }
+
+ checkClosed();
+
+ try{
+ this->impl->shutdownOutput();
+ this->outputShutdown = true;
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Socket::getSoLinger() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_LINGER );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setSoLinger( bool state, int timeout )
+ throw( SocketException, IllegalArgumentException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+
+ if( state && timeout < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Timeout value passed is invalid: %d", timeout );
+ }
+
+ int value = state ? ( 65535 > timeout ? timeout : 65535 ) : -1;
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_LINGER, value );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool Socket::getKeepAlive() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_KEEPALIVE ) == 0 ? false : true;
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setKeepAlive( bool keepAlive ) throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_KEEPALIVE, keepAlive ? 1 : 0 );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Socket::getReceiveBufferSize() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_RCVBUF );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setReceiveBufferSize( int size )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException ) {
+
+ checkClosed();
+
+ if( size <= 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Buffer size given was invalid: %d", size );
+ }
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_RCVBUF, size );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool Socket::getReuseAddress() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_REUSEADDR ) == 0 ? false : true;
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setReuseAddress( bool reuse ) throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_REUSEADDR, reuse ? 1 : 0 );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Socket::getSendBufferSize() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_SNDBUF );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setSendBufferSize( int size )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException ) {
+
+ checkClosed();
+
+ if( size <= 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Buffer size given was invalid: %d", size );
+ }
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_SNDBUF, size );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Socket::getSoTimeout() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_TIMEOUT );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setSoTimeout( int timeout )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException ) {
+
+ checkClosed();
+
+ if( timeout < 0 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Socket timeout given was invalid: %d", timeout );
+ }
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_TIMEOUT, timeout );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool Socket::getTcpNoDelay() const throw ( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_TCP_NODELAY ) == 0 ? false : true;
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setTcpNoDelay( bool value ) throw ( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_TCP_NODELAY, value ? 1 : 0 );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int Socket::getTrafficClass() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_IP_TOS );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setTrafficClass( int value )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException ) {
+
+ checkClosed();
+
+ if( value < 0 || value > 255 ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Value of the Traffic class option was invalid: %d", value );
+ }
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_IP_TOS, value );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_RETHROW( IllegalArgumentException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool Socket::getOOBInline() const throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ return this->impl->getOption( SocketOptions::SOCKET_OPTION_OOBINLINE ) == 0 ? false : true;
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setOOBInline( bool value ) throw( SocketException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ this->impl->setOption( SocketOptions::SOCKET_OPTION_OOBINLINE, value ? 1 : 0 );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::sendUrgentData( int data ) throw( decaf::io::IOException ) {
+
+ checkClosed();
+
+ try{
+ ensureCreated();
+ this->impl->sendUrgentData( data & 0xFF );
+ }
+ DECAF_CATCH_RETHROW( SocketException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, SocketException )
+ DECAF_CATCHALL_THROW( SocketException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::checkClosed() const throw( decaf::io::IOException ) {
+ if( this->closed ) {
+ throw IOException( __FILE__, __LINE__, "Socket already closed." );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::ensureCreated() const throw( decaf::io::IOException ) {
+
+ try{
+ if( !this->created ) {
+ this->impl->create();
+ this->created = true;
+ }
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::setSocketImplFactory( SocketImplFactory* factory )
+ throw( decaf::io::IOException,
+ decaf::net::SocketException ) {
+
+ if( Socket::factory != NULL ) {
+ throw SocketException(
+ __FILE__, __LINE__, "A SocketInplFactory was already set." );
+ }
+
+ Socket::factory = factory;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Socket::accepted() {
+
+ this->created = true;
+ this->bound = true;
+ this->connected = true;
+}
Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.h?rev=932637&r1=932636&r2=932637&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/Socket.h Fri Apr 9 22:17:38 2010
@@ -17,182 +17,527 @@
#ifndef _DECAF_NET_SOCKET_H_
#define _DECAF_NET_SOCKET_H_
+#include <decaf/net/SocketImplFactory.h>
#include <decaf/net/SocketException.h>
#include <decaf/io/InputStream.h>
#include <decaf/io/OutputStream.h>
#include <decaf/io/Closeable.h>
#include <decaf/util/Config.h>
-#include <apr_network_io.h>
+#include <decaf/lang/exceptions/NullPointerException.h>
+#include <decaf/lang/exceptions/IllegalArgumentException.h>
+#include <decaf/net/UnknownHostException.h>
+#include <decaf/net/SocketTimeoutException.h>
+#include <decaf/io/IOException.h>
namespace decaf{
namespace net{
+ class SocketImpl;
+ class ServerSocket;
+
+ /**
+ *
+ * @since 1.0
+ */
class DECAF_API Socket : public decaf::io::Closeable {
+ private:
+
+ // Factory for creating sockets, if not set a Plan TCP Socket is created
+ static SocketImplFactory* factory;
+
+ // The actual Socket that this Socket represents.
+ mutable SocketImpl* impl;
+ mutable volatile bool created;
+
+ bool connected;
+ bool closed;
+ bool bound;
+ bool inputShutdown;
+ bool outputShutdown;
+
+ friend class ServerSocket;
+
public:
/**
- * Define the SocketHandle type.
+ * Creates an unconnected Socket using the set SocketImplFactory or if non is set
+ * than the default SockImpl type is created.
*/
- typedef apr_socket_t* SocketHandle;
+ Socket();
/**
- * Define the SocketAddress type
+ * Creates a Socket wrapping the provided SocketImpl instance, this Socket is
+ * considered unconnected. The Socket class takes ownership of this SocketImpl
+ * pointer and will delete it when the Socket class is destroyed.
+ *
+ * @param impl
+ * The SocketImpl instance to wrap.
+ *
+ * @throws NullPointerException if the passed SocketImpl is Null.
*/
- typedef apr_sockaddr_t* SocketAddress;
+ Socket( SocketImpl* impl );
- public:
+ /**
+ * Creates a new Socket instance and connects it to the given host and port. If
+ * there is a SocketImplFactory set then the SokcetImpl is created using the factory
+ * otherwise the default Socket implementation is used.
+ *
+ * If the host parameter is empty then the loop back address is used.
+ *
+ * @param host
+ * The host name or IP address to connect to, empty string means loopback.
+ * @param port
+ * The port number to connect to [0...65535]
+ *
+ * @throws UnknownHostException if the host cannot be resolved.
+ * @throws IOException if an I/O error occurs while connecting the Socket.
+ * @throws IllegalArgumentException if the port if not in range [0...65535]
+ */
+ Socket( const std::string& host, int port );
+
+ /**
+ * Creates a new Socket instance and connects it to the given host and port. If
+ * there is a SocketImplFactory set then the SokcetImpl is created using the factory
+ * otherwise the default Socket implementation is used.
+ *
+ * If the host parameter is empty then the loop back address is used.
+ *
+ * @param host
+ * The host name or IP address to connect to, empty string means loopback.
+ * @param port
+ * The port number to connect to [0...65535]
+ * @param localAddress
+ * The IP address on the local machine to bind to.
+ * @param localPort
+ * The port on the local machine to bind to.
+ *
+ * @throws UnknownHostException if the host cannot be resolved.
+ * @throws IOException if an I/O error occurs while connecting the Socket.
+ * @throws IllegalArgumentException if the port if not in range [0...65535]
+ */
+ Socket( const std::string& host, int port, const std::string& localAddress, int localPort );
- virtual ~Socket() {}
+ virtual ~Socket();
/**
- * Connects to the specified destination. Closes this socket if
- * connected to another destination.
- * @param host The host of the server to connect to.
- * @param port The port of the server to connect to.
+ * Binds this Socket to the given local address and port. If the SocketAddress
+ * value is NULL then the Socket will be bound to an available local address and
+ * port.
+ *
+ * @param ipaddress
+ * The local address and port to bind the socket to.
+ * @param port
+ * The port on the local machine to bind to.
+ *
+ * @throws IOException if an error occurs during the bind operation.
+ * @throws IllegalArgumentException if the Socket can't process the subclass of SocketAddress
+ * that has been provided.
+ */
+ virtual void bind( const std::string& ipaddress, int port )
+ throw( decaf::io::IOException, decaf::lang::exceptions::IllegalArgumentException );
+
+ /**
+ * Closes the Socket. Once closed a Socket cannot be connected or otherwise
+ * operated upon, a new Socket instance must be created.
+ *
+ * @throws IOException if an I/O error occurs while closing the Socket.
+ */
+ virtual void close() throw( decaf::io::IOException );
+
+ /**
+ * Connects to the specified destination.
+ *
+ * @param host
+ * The host name or IP address of the remote host to connect to.
+ * @param port
+ * The port on the remote host to connect to.
+ *
+ * @throws IOException Thrown if a failure occurred in the connect.
+ * @throws IllegalArguementException if the timeout value is negative or the endpoint is invalid.
+ */
+ virtual void connect( const std::string& host, int port )
+ throw( decaf::io::IOException,
+ decaf::lang::exceptions::IllegalArgumentException );
+
+ /**
+ * Connects to the specified destination, with a specified timeout value. If a connection
+ * to the remote host is not established within the specified timeout interval than an
+ * SocketTimeoutException is thrown. A timeout value of zero is treated as an inifinite
+ * timeout.
+ *
+ * @param host
+ * The host name or IP address of the remote host to connect to.
+ * @param port
+ * The port on the remote host to connect to.
+ * @param timeout
+ * The number of Milliseconds to wait before treating the connection as failed.
+ *
* @throws IOException Thrown if a failure occurred in the connect.
+ * @throws SocketTimeoutException if the timeout for connection is exceeded.
+ * @throws IllegalArguementException if the timeout value is negative or the endpoint is invalid.
*/
- virtual void connect( const char* host, int port )
- throw(SocketException) = 0;
+ virtual void connect( const std::string& host, int port, int timeout )
+ throw( decaf::io::IOException,
+ decaf::net::SocketTimeoutException,
+ decaf::lang::exceptions::IllegalArgumentException );
/**
- * Indicates whether or not this socket is connected to a destination.
- * @returns true if connected
+ * Indicates whether or not this socket is connected to am end point.
+ *
+ * @returns true if connected, false otherwise.
+ */
+ bool isConnected() const {
+ return connected;
+ }
+
+ /**
+ * @returns true if the Socket has been closed.
+ */
+ bool isClosed() const {
+ return closed;
+ }
+
+ /**
+ * @returns true if this Socket has been bound to a Local address.
*/
- virtual bool isConnected() const = 0;
+ bool isBound() const {
+ return bound;
+ }
/**
- * Gets the InputStream for this socket.
- * @return The InputStream for this socket. NULL if not connected.
+ * @returns true if input on this Socket has been shutdown.
*/
- virtual io::InputStream* getInputStream() = 0;
+ bool isInputShutdown() const {
+ return inputShutdown;
+ }
/**
- * Gets the OutputStream for this socket.
- * @return the OutputStream for this socket. NULL if not connected.
+ * @returns true if output on this Socket has been shutdown.
*/
- virtual io::OutputStream* getOutputStream() = 0;
+ bool isOutputShutdown() const {
+ return outputShutdown;
+ }
/**
- * Gets the set Connect timeout, Socket implementations that support this
- * setting will throw an SocketException if they cannot connect within the
- * specified timeout.
+ * Gets the InputStream for this socket if its connected. The pointer returned is the
+ * property of the associated Socket and should not be deleted by the caller.
*
- * @returns The time in Milliseconds to wait for a connection to be made.
+ * When the returned InputStream is performing a blocking operation and the underlying
+ * connection is closed or otherwise broker the read calls will normally throw an exception
+ * to indicate the failure.
*
- * @throws SocketException if the operation fails.
+ * Closing the InputStream will also close the underlying Socket.
+ *
+ * @return The InputStream for this socket.
+ *
+ * @throws IOException if an error occurs during creation of the InputStream, also if the
+ * Socket is not connected or the input has been shutdown previously.
*/
- virtual int getConnectTimeout() const throw( SocketException ) = 0;
+ virtual decaf::io::InputStream* getInputStream() throw( decaf::io::IOException );
/**
- * Sets the set Connect timeout, Socket implementations that support this
- * setting will throw an SocketException if they cannot connect within the
- * specified timeout.
+ * Gets the OutputStream for this socket if it is connected. The pointer returned is the
+ * property of the Socket instance and should not be deleted by the caller.
*
- * @param timeout
- * The time in Milliseconds to wait for a connection to be made.
+ * Closing the returned Socket will also close the underlying Socket.
*
- * @throws SocketException if the operation fails.
+ * @return the OutputStream for this socket.
+ *
+ * @throws IOException if an error occurs during the creation of this OutputStream, or
+ * if the Socket is closed or the output has been shutdown previously.
+ */
+ virtual decaf::io::OutputStream* getOutputStream() throw( decaf::io::IOException );
+
+ /**
+ * Gets the on the remote host this Socket is connected to.
+ *
+ * @return the port on the remote host the socket is connected to, or 0 if not connected.
+ */
+ int getPort() const;
+
+ /**
+ * Gets the local port the socket is bound to.
+ *
+ * @return the local port the socket was bound to, or -1 if the socket is not bound.
+ */
+ int getLocalPort() const;
+
+ /**
+ * Returns the address to which the socket is connected.
+ *
+ * @returns the remote IP address to which this socket is connected, or null if the socket is not connected.
+ */
+ std::string getInetAddress() const;
+
+ /**
+ * Gets the local address to which the socket is bound.
+ *
+ * @returns the local address to which the socket is bound or InetAddress.anyLocalAddress() if the socket is not bound yet.
+ */
+ std::string getLocalAddress() const;
+
+ /**
+ * Shuts down the InputStream for this socket essentially marking it as EOF. The stream
+ * returns EOF for any calls to read after this method has been called.
+ *
+ * @throws IOException if an I/O error occurs while performing this operation.
+ */
+ void shutdownInput() throw( decaf::io::IOException );
+
+ /**
+ * Shuts down the OutputStream for this socket, any data already written to the socket will
+ * be sent, any further calls to OuputStream::write will throw an IOException.
+ *
+ * @throws IOException if an I/O error occurs while performing this operation.
*/
- virtual void setConnectTimeout( int timeout ) throw( SocketException ) = 0;
+ void shutdownOutput() throw( decaf::io::IOException );
/**
- * Gets the linger time.
+ * Gets the linger time for the socket, SO_LINGER. A return value of -1 indicates that
+ * the option is disabled.
+ *
* @return The linger time in seconds.
+ *
* @throws SocketException if the operation fails.
*/
- virtual int getSoLinger() const throw( SocketException ) = 0;
+ virtual int getSoLinger() const throw( SocketException );
/**
- * Sets the linger time.
- * @param linger The linger time in seconds. If 0, linger is off.
+ * Sets the linger time (SO_LINGER) using a specified time value, this limits of this
+ * value are platform specific.
+ *
+ * @param state
+ * The state of SO_LINGER, true is on.
+ * @param timeout
+ * The linger time in seconds, must be non-negative.
+ *
* @throws SocketException if the operation fails.
+ * @throws IllegalArgumentException if state is true and timeout is negative.
*/
- virtual void setSoLinger( int linger ) throw( SocketException ) = 0;
+ virtual void setSoLinger( bool state, int timeout )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException );
/**
- * Gets the keep alive flag.
- * @return True if keep alive is enabled.
+ * Gets the keep alive flag for this socket, SO_KEEPALIVE.
+ *
+ * @return true if keep alive is enabled for this socket.
+ *
* @throws SocketException if the operation fails.
*/
- virtual bool getKeepAlive() const throw( SocketException ) = 0;
+ virtual bool getKeepAlive() const throw( SocketException );
/**
- * Enables/disables the keep alive flag.
- * @param keepAlive If true, enables the flag.
+ * Enables/disables the keep alive flag for this socket, SO_KEEPALIVE.
+ *
+ * @param keepAlive
+ * If true, enables the flag.
+ *
* @throws SocketException if the operation fails.
*/
- virtual void setKeepAlive( bool keepAlive ) throw( SocketException ) = 0;
+ virtual void setKeepAlive( bool keepAlive ) throw( SocketException );
/**
- * Gets the receive buffer size.
+ * Gets the receive buffer size for this socket, SO_RCVBUF. This is the buffer used
+ * by the underlying platform socket to buffer received data.
+ *
* @return the receive buffer size in bytes.
+ *
* @throws SocketException if the operation fails.
*/
- virtual int getReceiveBufferSize() const throw( SocketException ) = 0;
+ virtual int getReceiveBufferSize() const throw( SocketException );
/**
- * Sets the receive buffer size.
- * @param size Number of bytes to set the receive buffer to.
+ * Sets the receive buffer size for this socket, SO_RCVBUF.
+ *
+ * @param size
+ * Number of bytes to set the receive buffer to.
+ *
* @throws SocketException if the operation fails.
+ * @throws IllegalArgumentException if the value is zero or negative.
*/
- virtual void setReceiveBufferSize( int size ) throw( SocketException ) = 0;
+ virtual void setReceiveBufferSize( int size )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException );
/**
- * Gets the reuse address flag.
+ * Gets the reuse address flag, SO_REUSEADDR.
+ *
* @return True if the address can be reused.
+ *
* @throws SocketException if the operation fails.
*/
- virtual bool getReuseAddress() const throw( SocketException ) = 0;
+ virtual bool getReuseAddress() const throw( SocketException );
/**
- * Sets the reuse address flag.
- * @param reuse If true, sets the flag.
+ * Sets the reuse address flag, SO_REUSEADDR.
+ *
+ * @param reuse
+ * If true, sets the flag.
+ *
* @throws SocketException if the operation fails.
*/
- virtual void setReuseAddress( bool reuse ) throw( SocketException ) = 0;
+ virtual void setReuseAddress( bool reuse ) throw( SocketException );
/**
- * Gets the send buffer size.
+ * Gets the send buffer size for this socket, SO_SNDBUF, this value is used by the platform
+ * socket to buffer data written to the socket.
+ *
* @return the size in bytes of the send buffer.
+ *
* @throws SocketException if the operation fails.
*/
- virtual int getSendBufferSize() const throw( SocketException ) = 0;
+ virtual int getSendBufferSize() const throw( SocketException );
/**
- * Sets the send buffer size.
- * @param size The number of bytes to set the send buffer to.
+ * Gets the send buffer size for this socket, SO_SNDBUF, this value is used by the platform
+ * socket to buffer data written to the socket.
+ *
+ * @param size
+ * The number of bytes to set the send buffer to, must be larger than zero.
+ *
* @throws SocketException if the operation fails.
+ * @throws IllegalArgumentException if the value is zero or negative.
*/
- virtual void setSendBufferSize( int size ) throw( SocketException ) = 0;
+ virtual void setSendBufferSize( int size )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException );
/**
- * Gets the timeout for socket operations.
+ * Gets the timeout for socket operations, SO_TIMEOUT.
+ *
* @return The timeout in milliseconds for socket operations.
+ *
* @throws SocketException Thrown if unable to retrieve the information.
*/
- virtual int getSoTimeout() const throw( SocketException ) = 0;
+ virtual int getSoTimeout() const throw( SocketException );
+
+ /**
+ * Sets the timeout for socket operations, SO_TIMEOUT. A value of zero indicates that timeout
+ * is infinite for operations on this socket.
+ *
+ * @param timeout
+ * The timeout in milliseconds for socket operations.
+ *
+ * @throws SocketException Thrown if unable to set the information.
+ * @throws IllegalArgumentException if the timeout value is negative.
+ */
+ virtual void setSoTimeout( int timeout )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException );
/**
- * Sets the timeout for socket operations.
- * @param timeout The timeout in milliseconds for socket operations.<p>
+ * Gets the Status of the TCP_NODELAY setting for this socket.
+ *
+ * @returns true if TCP_NODELAY is enabled for the socket.
+ *
+ * @throws SocketException Thrown if unable to set the information.
+ */
+ virtual bool getTcpNoDelay() const throw ( SocketException );
+
+ /**
+ * Sets the Status of the TCP_NODELAY param for this socket., this setting is used
+ * to disable or enable Nagle's algorithm on the Socket.
+ *
+ * @param value
+ * The setting for the socket's TCP_NODELAY option, true to enable.
+ *
* @throws SocketException Thrown if unable to set the information.
*/
- virtual void setSoTimeout( int timeout ) throw( SocketException ) = 0;
+ virtual void setTcpNoDelay( bool value ) throw ( SocketException );
/**
- * Gets the Status of the TCP_NODELAY param for this socket as a Bool
- * @returns true if TCP_NODELAY is enabled
- * @throws Exception
+ * Gets the Traffic Class setting for this Socket, sometimes referred to as Type of
+ * Service setting. This setting is dependent on the underlying network implementation
+ * for the platform this Socket runs on and is not guaranteed to have any effect.
+ *
+ * Refer to your platforms network documentation regarding support for this setting.
+ *
+ * @returns the bitset result of querying the traffic class setting.
+ *
+ * @throws SocketException if an error is encountered while performing this operation.
*/
- virtual bool getTcpNoDelay() const throw ( decaf::lang::Exception ) = 0;
+ virtual int getTrafficClass() const throw( SocketException );
/**
- * Sets the Status of the TCP_NODELAY param for this socket as a Bool
- * @param value - true if TCP_NODELAY is to be enabled
- * @throws Exception
+ * Gets the Traffic Class setting for this Socket, sometimes referred to as Type of
+ * Service setting. This setting is dependent on the underlying network implementation
+ * for the platform this Socket runs on and is not guaranteed to have any effect.
+ *
+ * Refer to your platforms network documentation regarding support for this setting.
+ *
+ * @param value
+ * The integer value representing the traffic class setting bitset.
+ *
+ * @throws SocketException if an error is encountered while performing this operation.
+ * @throws IllegalArgumentException if the value is not in the range [0..255].
*/
- virtual void setTcpNoDelay( bool value ) throw ( decaf::lang::Exception ) = 0;
+ virtual void setTrafficClass( int value )
+ throw( SocketException, decaf::lang::exceptions::IllegalArgumentException );
+
+ /**
+ * Gets the value of the OOBINLINE for this socket.
+ *
+ * @return true if OOBINLINE is enabled, false otherwise.
+ *
+ * @throws SocketException if an error is encountered while performing this operation.
+ */
+ bool getOOBInline() const throw( SocketException );
+
+ /**
+ * Sets the value of the OOBINLINE for this socket, by default this option is disabled. If
+ * enabled the urgent data is read inline on the Socket's InputStream, no notification is give.
+ *
+ * @return true if OOBINLINE is enabled, false otherwise.
+ *
+ * @throws SocketException if an error is encountered while performing this operation.
+ */
+ void setOOBInline( bool value ) throw( SocketException );
+
+ /**
+ * Sends on byte of urgent data to the Socket.
+ *
+ * @param data
+ * The value to write as urgent data, only the lower eight bits are sent.
+ *
+ * @throws IOException if an I/O error occurs while performing this operation.
+ */
+ void sendUrgentData( int data ) throw( decaf::io::IOException );
+
+ /**
+ * @returns a string representing this Socket.
+ */
+ std::string toString() const;
+
+ public:
+
+ /**
+ * Sets the instance of a SocketImplFactory that the Socket class should use when new
+ * instances of this class are created. This method is only allowed to be used once
+ * during the lifetime of the application.
+ *
+ * @param factory
+ * The instance of a SocketImplFactory to use when new Socket objects are created.
+ *
+ * @throws IOException if an I/O error occurs while performing this operation.
+ * @throws SocketException if this method has already been called with a valid factory.
+ */
+ static void setSocketImplFactory( SocketImplFactory* factory )
+ throw( decaf::io::IOException,
+ decaf::net::SocketException );
+
+ protected:
+
+ // Flags the Socket instance as created, bound and connected when its connected
+ // via a ServerSocket accept call.
+ void accepted();
+
+ // Sets up a connected socket for the constructors that take connection arguments.
+ void initSocketImpl( const std::string& address, int port, const std::string& localAddress, int localPort )
+ throw( decaf::io::IOException, decaf::net::UnknownHostException );
+
+ // Check for already closed and throw an error if so.
+ void checkClosed() const throw( decaf::io::IOException );
+
+ // Create but don't connect the underlying OS Socket instance, if not already created.
+ void ensureCreated() const throw( decaf::io::IOException );
};
Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketAddress.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketAddress.h?rev=932637&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketAddress.h (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketAddress.h Fri Apr 9 22:17:38 2010
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DECAF_NET_SOCKETADDRESS_H_
+#define _DECAF_NET_SOCKETADDRESS_H_
+
+#include <decaf/util/Config.h>
+
+namespace decaf {
+namespace net {
+
+ /**
+ * Base class for protocol specific Socket addresses. These classes provide an
+ * immutable address object that is used by the Socket classes.
+ *
+ * @since 1.0
+ */
+ class DECAF_API SocketAddress {
+ public:
+
+ virtual ~SocketAddress() {}
+
+ };
+
+}}
+
+#endif /* _DECAF_NET_SOCKETADDRESS_H_ */
Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketAddress.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketImpl.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketImpl.cpp?rev=932637&r1=932636&r2=932637&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketImpl.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/SocketImpl.cpp Fri Apr 9 22:17:38 2010
@@ -24,7 +24,7 @@ using namespace decaf::net;
using namespace decaf::lang;
////////////////////////////////////////////////////////////////////////////////
-SocketImpl::SocketImpl() {
+SocketImpl::SocketImpl() : port(0), localPort(0), address() {
}
////////////////////////////////////////////////////////////////////////////////
@@ -34,8 +34,15 @@ SocketImpl::~SocketImpl() {
////////////////////////////////////////////////////////////////////////////////
std::string SocketImpl::toString() const {
- std::string result = std::string( "Socket[addr=" ) + this->hostname +
+ std::string result = std::string( "Socket[addr=" ) + this->address +
",port=" + Integer::toString( this->port ) + "]";
return result;
}
+
+////////////////////////////////////////////////////////////////////////////////
+void SocketImpl::sendUrgentData( int data ) throw( decaf::io::IOException ) {
+
+ throw decaf::io::IOException(
+ __FILE__, __LINE__, "Urgent Data not supported by this implementation." );
+}