00001
00014
00015
00016 #include <errno.h>
00017 #include <cstring>
00018
00019 #include "Socket.h"
00020 #include "SystemCall.h"
00021
00022
00024
00025
00026
00027
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
00040 SOCKET Socket::getDescriptor() const throw()
00041 {
00042 return socketHandle;
00043 }
00044
00045
00046 bool Socket::operator==(const Socket& socket) const throw()
00047 {
00048 return getDescriptor() == socket.getDescriptor();
00049 }
00050
00051
00052 bool Socket::operator<(const Socket& socket) const throw()
00053 {
00054 return getDescriptor() < socket.getDescriptor();
00055 }
00056
00057
00058 bool Socket::isOpen() const throw()
00059 {
00060 return getDescriptor() != static_cast<SOCKET>(-1);
00061 }
00062
00063
00064 Socket::Socket(SOCKET descriptor) : socketHandle(descriptor),autoClosing(true),flags_(0)
00065 {
00066 }
00067
00068
00069 void Socket::setDescriptor(SOCKET descriptor) throw()
00070 {
00071 socketHandle = descriptor;
00072 }
00073
00074
00075 Socket::operator SOCKET() const throw()
00076 {
00077 return socketHandle;
00078 }
00079
00080
00081
00082 bool Socket::getBoolOption(int code) const
00083 {
00084 return getOption(code) ? true : false;
00085 }
00086
00087
00088 void Socket::setOption(int code, int value)
00089 {
00090 setOption(code,&value,sizeof(value));
00091 }
00092
00093
00094 void Socket::setBoolOption(int code, bool flag)
00095 {
00096 setOption(code,flag);
00097 }
00098
00099
00100 int Socket::getSocketType() const
00101 {
00102 return getOption(SO_TYPE);
00103 }
00104
00105
00106 int Socket::getAndClearErrorStatus()
00107 {
00108 return getOption(SO_ERROR);
00109 }
00110
00111
00112
00113 bool Socket::getRouting() const
00114 {
00115 return !getBoolOption(SO_DONTROUTE);
00116 }
00117
00118
00119 void Socket::setRouting( bool flag )
00120 {
00121 setBoolOption(SO_DONTROUTE,!flag);
00122 }
00123
00124
00125 bool Socket::canLocalAddressesBeReused() const
00126 {
00127 return getBoolOption(SO_REUSEADDR);
00128 }
00129
00130
00131 void Socket::setReuseLocalAddresses(bool flag)
00132 {
00133 setBoolOption(SO_REUSEADDR,flag);
00134 }
00135
00136
00137 bool Socket::isAutoClosing() const throw()
00138 {
00139 return autoClosing;
00140 }
00141
00142
00143 void Socket::setToAutoClose( bool flag ) throw()
00144 {
00145 autoClosing = flag;
00146 }
00147
00148
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
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
00169 Socket::~Socket()
00170 {
00171 try {
00172 if ( isAutoClosing() )
00173 close();
00174 }
00175 catch (...)
00176 {
00177 }
00178 }
00179
00180
00181 int Socket::getReceivingBufferSize() const
00182 {
00183 return getOption( SO_RCVBUF );
00184 }
00185
00186
00187
00188 void Socket::setReceivingBufferSize( int size )
00189 {
00190 setOption( SO_RCVBUF, size );
00191 }
00192
00193
00194 int Socket::getSendingBufferSize() const
00195 {
00196 return getOption( SO_SNDBUF );
00197 }
00198
00199
00200
00201 void Socket::setSendingBufferSize( int size )
00202 {
00203 setOption( SO_SNDBUF, size );
00204 }
00205
00206
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
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
00223
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
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
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
00254 void Socket::shutdownSocketReceives()
00255 {
00256 shutdown(ShutdownReceive);
00257 }
00258
00259
00260 void Socket::shutdownSocketSends()
00261 {
00262 shutdown(ShutdownSend);
00263 }
00264
00265
00266 void Socket::shutdown()
00267 {
00268 shutdown(ShutdownBoth);
00269 }
00270
00271
00272 void Socket::shutdown(SocketShutdownMode code)
00273 {
00274 int dummy;
00275 SOCKET_CALL_2(dummy =,::shutdown,getDescriptor(),code)
00276 }
00277
00278
00279
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
00288 void Socket::close()
00289 {
00290 ::closesocket(socketHandle);
00291 socketHandle = static_cast<SOCKET>(-1);
00292 }
00293
00294
00295 void Socket::reset( int type, int domain, int protocol )
00296 {
00297 try {
00298 close();
00299 }
00300 catch (std::exception&) {
00301
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
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
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 }