Socket.cpp

Go to the documentation of this file.
00001 
00014 // Socket.cpp -- implementation for the Socket class
00015 
00016 #include <errno.h>
00017 #include <cstring>
00018 
00019 #include "Socket.h"
00020 #include "SystemCall.h"
00021 
00022 
00024 // class Socket
00025 
00026 
00027 // standard c++ iostream inserter
00028 std::ostream& Socket::operator<<(std::ostream& stream) const
00029 {
00030         stream << "Socket( ";
00031         if ( isOpen() )
00032                 stream << getDescriptor();
00033         else
00034                 stream << "Socket is not open";
00035         stream << " )";
00036         return stream;
00037 }
00038 
00039 // Return the native operating system socket handle
00040 SOCKET Socket::getDescriptor() const throw()
00041 {
00042         return socketHandle;
00043 }
00044 
00045 // Comparison to another socket object
00046 bool Socket::operator==(const Socket& socket) const throw()
00047 {
00048         return getDescriptor() == socket.getDescriptor();
00049 }
00050 
00051 // Comparison to another socket object
00052 bool Socket::operator<(const Socket& socket) const throw()
00053 {
00054         return getDescriptor() < socket.getDescriptor();
00055 }
00056 
00057 // Whether the socket has been open or not
00058 bool Socket::isOpen() const throw()
00059 {
00060         return getDescriptor() != static_cast<SOCKET>(-1);
00061 }
00062 
00063 // Construct using the native operating system socket handle
00064 Socket::Socket(SOCKET descriptor) : socketHandle(descriptor),autoClosing(true),flags_(0)
00065 {
00066 }
00067 
00068 // Specify the native operating system socket handle
00069 void Socket::setDescriptor(SOCKET descriptor) throw()
00070 {
00071         socketHandle = descriptor;
00072 }
00073 
00074 // Return the native operating system socket handle
00075 Socket::operator SOCKET() const throw()
00076 {
00077         return socketHandle;
00078 }
00079 
00080 
00081 // Retrieve whether a boolean socket option is set
00082 bool Socket::getBoolOption(int code) const
00083 {
00084         return getOption(code) ? true : false;
00085 }
00086 
00087 // Specify an integral socket option
00088 void Socket::setOption(int code, int value)
00089 {
00090         setOption(code,&value,sizeof(value));
00091 }
00092 
00093 // Specify a boolean socket option
00094 void Socket::setBoolOption(int code, bool flag)
00095 {
00096         setOption(code,flag);
00097 }
00098 
00099 // The type of socket (ie, SOCK_STREAM,SOCK_DGRAM,SOCK_RAW, etc.)
00100 int Socket::getSocketType() const
00101 {
00102         return getOption(SO_TYPE);
00103 }
00104 
00105 // Retrieves error status and clears the status
00106 int Socket::getAndClearErrorStatus()
00107 {
00108         return getOption(SO_ERROR);
00109 }
00110 
00111 // Retrieve whether routing is enabled
00112 // The default option is false for the SO_DONTROUTE
00113 bool Socket::getRouting() const
00114 {
00115         return !getBoolOption(SO_DONTROUTE);
00116 }
00117 
00118 // Specify whether the socket should use routing
00119 void Socket::setRouting( bool flag )
00120 {
00121         setBoolOption(SO_DONTROUTE,!flag);
00122 }
00123 
00124 // Retrieve whether the address to which this socket is bound can be used by others
00125 bool Socket::canLocalAddressesBeReused() const
00126 {
00127         return getBoolOption(SO_REUSEADDR);
00128 }
00129 
00130 // Specify whether the address to which this socket is bound can be used by others
00131 void Socket::setReuseLocalAddresses(bool flag)
00132 {
00133         setBoolOption(SO_REUSEADDR,flag);
00134 }
00135 
00136 // Retrieve whether the Socket will close the native socket on destruction
00137 bool Socket::isAutoClosing() const throw()
00138 {
00139         return autoClosing;
00140 }
00141 
00142 // Specify whether or not the destructor will close the native socket
00143 void Socket::setToAutoClose( bool flag ) throw()
00144 {
00145         autoClosing = flag;
00146 }
00147 
00148 // Associates a local address with a socket
00149 void Socket::bind( const SocketAddress& address )
00150 {
00151         sockaddr_in in= address.operator sockaddr_in();
00152         bind(reinterpret_cast<sockaddr*>(&in),sizeof(sockaddr));
00153 }
00154 
00155 
00156 // Constuct with given parameters
00157 Socket::Socket(int type,int domain,int protocol) : socketHandle( static_cast<SOCKET>(-1) ),
00158         autoClosing( true ),flags_( 0 )
00159 {
00160         int result;
00161         SOCKET_CALL_3( result = (int), ::socket, domain, type, protocol )
00162 
00163         if ( result >= 0 ) {
00164                 setDescriptor(result);
00165         }
00166 }
00167 
00168 // Socket destructor
00169 Socket::~Socket()
00170 {
00171         try {
00172                 if ( isAutoClosing() )
00173                         close();
00174         }
00175         catch (...)
00176         {
00177         }
00178 }
00179 
00180 // Return the size of the operating system's socket buffer
00181 int Socket::getReceivingBufferSize() const
00182 {
00183         return getOption( SO_RCVBUF );
00184 }
00185 
00186 // Sets the size of the operating system's socket buffer
00187 // On Windows the default buffer size is 8K
00188 void Socket::setReceivingBufferSize( int size )
00189 {
00190         setOption( SO_RCVBUF, size );
00191 }
00192 
00193 // Return the size of the operating system's socket buffer
00194 int Socket::getSendingBufferSize() const
00195 {
00196         return getOption( SO_SNDBUF );
00197 }
00198 
00199 // Sets the size of the operating system's socket buffer
00200 // On Windows the default buffer size is 8K
00201 void Socket::setSendingBufferSize( int size )
00202 {
00203         setOption( SO_SNDBUF, size );
00204 }
00205 
00206 // Associates a local address with a socket
00207 void Socket::bind( sockaddr* address, int size )
00208 {
00209         int dummy;
00210         SOCKET_CALL_3( dummy =, ::bind, getDescriptor(), (sockaddr*) address, size )
00211 }
00212 
00213 // Retrieve the interger socket option
00214 int Socket::getOption( int code ) const
00215 {
00216         int result = 0;
00217         int size = sizeof( result );
00218         getOption( code, &result, size );
00219         return result;
00220 }
00221 
00222 // Retrieve the length of time the socket will wait for unsent data
00223 // before the socket is closed and whether it is set
00224 bool Socket::getLingerInformation( int& seconds ) const
00225 {
00226         linger lingerStruct;
00227         int size = sizeof(lingerStruct);
00228         getOption( SO_LINGER, &lingerStruct, size );
00229         seconds = lingerStruct.l_linger;
00230         return lingerStruct.l_onoff != 0;
00231 }
00232 
00233 // Specify the length of time to wait for unsent data before a socket is closed
00234 void Socket::setLingerInformation( bool flag, int seconds )
00235 {
00236         linger lingerStruct;
00237         lingerStruct.l_onoff = static_cast<unsigned short>(flag);
00238         lingerStruct.l_linger = static_cast<unsigned short>(seconds);
00239         setOption(SO_LINGER,&lingerStruct,sizeof( lingerStruct ) );
00240 }
00241 
00242 
00243 // IP Socket Address accessor
00244 SocketAddress Socket::getSocketAddress() const
00245 {
00246         SocketAddress address;
00247         sockaddr_in in = address.operator sockaddr_in();
00248         int size = static_cast<int>(sizeof(sockaddr));
00249         name( reinterpret_cast<sockaddr*>(&in), size);
00250         return address;
00251 }
00252 
00253 // Shutdown the socket receiving channel
00254 void Socket::shutdownSocketReceives()
00255 {
00256         shutdown(ShutdownReceive);
00257 }
00258 
00259 // Shutdown the socket send channel
00260 void Socket::shutdownSocketSends()
00261 {
00262         shutdown(ShutdownSend);
00263 }
00264 
00265 // Shutdown all socket channels
00266 void Socket::shutdown()
00267 {
00268         shutdown(ShutdownBoth);
00269 }
00270 
00271 // Shutdown socket
00272 void Socket::shutdown(SocketShutdownMode code)
00273 {
00274         int dummy;
00275         SOCKET_CALL_2(dummy =,::shutdown,getDescriptor(),code)
00276 }
00277 
00278 
00279 // Sets the given socket option
00280 void Socket::setOption( int code, void* storage, int size )
00281 {
00282         int dummy;
00283         SOCKET_CALL_5(dummy =,::setsockopt,getDescriptor(),SOL_SOCKET,code,
00284                 reinterpret_cast<char*>(storage),size)
00285 }
00286 
00287 // Close the socket
00288 void Socket::close()
00289 {
00290     ::closesocket(socketHandle);
00291         socketHandle = static_cast<SOCKET>(-1);
00292 }
00293 
00294 // Close my socket descriptor, then allocate a new socket.  
00295 void Socket::reset( int type, int domain, int protocol )
00296 {
00297         try {
00298                 close();
00299         }
00300         catch (std::exception&) {
00301                 // do nothing because we might not have been opened
00302     }
00303   
00304         int result = 0;
00305         SOCKET_CALL_3(result=(int),::socket,domain,type,protocol)
00306         if (result >= 0)
00307                 setDescriptor(result);
00308 }
00309 
00310 // Retrieve the given socket option
00311 void Socket::getOption( int code, void* storage, int& size ) const
00312 {
00313 #ifdef _MSC_VER
00314     int length = size;
00315 #else
00316         socklen_t length = size;
00317 #endif
00318 
00319         int dummy;
00320         SOCKET_CALL_5(dummy =,::getsockopt,getDescriptor(),SOL_SOCKET,code,
00321                 reinterpret_cast<char*>(storage),&length)
00322 }
00323 
00324 // Retrieve the socket's name
00325 void Socket::name( sockaddr* address, int& size ) const
00326 {
00327         int dummy;
00328 #ifdef _MSC_VER
00329     int length = size;
00330 #else
00331         socklen_t length = size;
00332 #endif
00333 
00334         SOCKET_CALL_3(dummy =,::getsockname,getDescriptor(),address,&length)
00335         size = length;
00336 }

Generated on Tue Mar 28 09:10:15 2006 for Simple SOAP by  doxygen 1.4.6