00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef CABAL_OS_WSA_H
00017 #define CABAL_OS_WSA_H
00018
00019 #include <string.h>
00020 #include <winsock2.h>
00021 #include <cabal_error.h>
00022 #include <string>
00023
00024 #define CABAL_INVALID_ADDR INADDR_ANY
00025 #define CABAL_MAX_IP_SIZE 21
00026
00027 namespace Cabal {
00028 typedef SOCKET RawSocket;
00029 typedef struct sockaddr_in SockAddrInet;
00030 typedef struct sockaddr SockAddr;
00031 typedef int socklen_t;
00032
00033 typedef unsigned short NetPort;
00034 typedef unsigned long NetAddr;
00035
00037 inline bool operator <( const SockAddrInet &in1, const SockAddrInet &in2 )
00038 {
00039 return (memcmp( &in1, &in2, sizeof(in2) )<0);
00040 }
00041
00043 inline bool operator ==( const SockAddrInet &in1, const SockAddrInet &in2 )
00044 {
00045 return (memcmp( &in1, &in2, sizeof(in2) )==0);
00046 }
00047
00048 }
00049
00050 #include <cabal_netbase.h>
00051
00052
00053 #define MSG_NOSIGNAL 0
00054
00055 namespace Cabal {
00056
00058 class Net_WSA: public NetBase
00059 {
00060 static int m_count;
00061
00062 public:
00063 static bool init() throw(InitError);
00064 static bool exit() throw(DataIncompleteError);
00065
00067 static RawSocket createTCPSocket() { return ::socket( AF_INET, SOCK_STREAM , 0); }
00068 static RawSocket createUDPSocket() { return ::socket( AF_INET, SOCK_DGRAM , 0); }
00069
00071 static int closeSocket( RawSocket s ) { return ::closesocket(s); }
00072
00073 static int bind( const RawSocket s, const SockAddrInet &addr )
00074 {
00075 return ( ::bind( s, reinterpret_cast<const SockAddr *>( &addr ), sizeof( SockAddrInet ) ) != -1);
00076 }
00077
00078 static bool connect( const RawSocket s, const SockAddrInet &addr )
00079 {
00080 return ( ::connect( s, reinterpret_cast<const SockAddr *>( &addr ), sizeof( SockAddrInet ) ) != -1 );
00081 }
00082
00084 static bool listen( const RawSocket s, const int incomingMax )
00085 {
00086 return ( ::listen( s, incomingMax ) == 0 );
00087 }
00088
00092 static RawSocket accept( const RawSocket s, SockAddrInet *in )
00093 {
00094 socklen_t len = sizeof( SockAddrInet );
00095 RawSocket ret = ::accept( s, reinterpret_cast<SockAddr *>(in), &len );
00096 if ( ret == -1 ) return INVALID_SOCKET;
00097 return ret;
00098 }
00100 static void initSockAddr( SockAddrInet &attr ) {
00101 attr.sin_family = AF_INET;
00102 attr.sin_port = 0;
00103 attr.sin_addr.s_addr = 0;
00104 }
00105
00106 static void initSockAddr( SockAddrInet &attr, const char *ip ) {
00107 attr.sin_family = AF_INET;
00108 attr.sin_port = 0;
00109 attr.sin_addr.s_addr = inet_addr( ip );
00110 }
00111
00112 static void initSockAddr( SockAddrInet &attr, const char *ip, const NetPort port ) {
00113 attr.sin_family = AF_INET;
00114 attr.sin_port = htons(port);
00115 attr.sin_addr.s_addr = inet_addr( ip );
00116 }
00117
00118 static void initSockAddr( SockAddrInet &attr, const NetAddr address, const NetPort port ) {
00119 attr.sin_family = AF_INET;
00120 attr.sin_port = htons(port);
00121 attr.sin_addr.s_addr = htonl( address );
00122 };
00123
00124 static bool SockAddrIsZero( const SockAddrInet &addr ) { return (addr.sin_addr.s_addr == 0); }
00125 static void SockAddrSetPort( SockAddrInet &addr, NetPort port ) {
00126 addr.sin_port = hostToNetPort( port );
00127 }
00128 static bool SockAddrIsSame( const SockAddrInet &addr, const SockAddrInet &addr1 ) {
00129 if ( addr.sin_addr.s_addr == addr1.sin_addr.s_addr && addr.sin_port == addr1.sin_port )
00130 return true;
00131 return false;
00132 }
00133 static NetPort SockAddrGetPort( const SockAddrInet &addr ) { return netToHostPort( addr.sin_port ); }
00134
00136 static bool getHostList(
00137 const std::string &name,
00138 std::string &real_name,
00139 char *real_ip,
00140 NetAddr *other_addrs, int na_count );
00141
00142 static bool addrToString( const SockAddrInet &addr, char *dest );
00143 static bool stringToAddr( const char *source, SockAddrInet &addr )
00144 {
00145 int size = CABAL_MAX_IP_SIZE;
00146 return (WSAStringToAddress(
00147 const_cast<char *>(source),
00148 AF_INET,
00149 NULL,
00150 reinterpret_cast<SockAddr *>(&addr),
00151 &size
00152 ) == 0);
00153 }
00154
00155 static bool isAddressString( const char *source ) {
00156 SockAddrInet addr;
00157 return stringToAddr( source, addr );
00158 }
00159
00160
00161 static int errorCode() { return WSAGetLastError(); }
00162 static std::string errorDescription( const int osCode );
00164 static void resetError() {}
00165
00166
00168 static RawSocket dup( RawSocket s )
00169 {
00170 WSAPROTOCOL_INFO proto_inf;
00171 if ( WSADuplicateSocket( s, GetCurrentProcessId(), &proto_inf ) == 0 )
00172 {
00173 s = WSASocket(
00174 FROM_PROTOCOL_INFO,
00175 FROM_PROTOCOL_INFO,
00176 FROM_PROTOCOL_INFO,
00177 &proto_inf,
00178 0,
00179 0 );
00180 if ( s == INVALID_SOCKET ) return static_cast<RawSocket>( -1 );
00181 return s;
00182 }
00183 return static_cast<RawSocket>(-1);
00184 }
00185
00186 static bool inProgress() { return WSAGetLastError() == WSAEWOULDBLOCK; }
00187 static bool errorAgain() { return WSAGetLastError() == WSAEWOULDBLOCK; }
00188 static bool errorAgain(int error) { return error == WSAEWOULDBLOCK; }
00189 static bool errorPipe() { return false; }
00190
00191 static void setNonBlocking( RawSocket s )
00192 {
00193 unsigned long mode = 1;
00194 ioctlsocket( s, FIONBIO, &mode );
00195 }
00196
00197 static void setBlocking( RawSocket s )
00198 {
00199 unsigned long mode = 0;
00200 ioctlsocket( s, FIONBIO, &mode );
00201 }
00202
00203 static void setTCPDefaults( const RawSocket s )
00204 {
00205 int iOpt;
00206 setsockopt( s, SOL_SOCKET, SO_KEEPALIVE,
00207 (const char *) &iOpt , sizeof( iOpt ));
00208 setsockopt( s, SOL_SOCKET, SO_REUSEADDR,
00209 (const char *) &iOpt, sizeof( iOpt ));
00210 }
00211
00212 static bool validSocket( const RawSocket s ) { return s != INVALID_SOCKET; }
00213 static void invalidate( RawSocket &s ) { s = INVALID_SOCKET; }
00214
00215 static int getSocketOption( const RawSocket s, const int level, int &iErrval )
00216 {
00217 int iErrvalLen = sizeof( int );
00218 return getsockopt( s,
00219 SOL_SOCKET,
00220 level,
00221 reinterpret_cast<char *>( &iErrval ),
00222 &iErrvalLen
00223 );
00224 }
00225
00226
00227 static int send( const RawSocket s, const void *buffer, const int len, const int params=0 ) {
00228 return ::send( s, static_cast<const char *>(buffer), len, params );
00229 }
00230
00231 static int recv( const RawSocket s, void *buffer, const int len, const int params=0 ) {
00232 return ::recv( s, static_cast<char *>(buffer), len, params );
00233 }
00234
00235 static int sendto(const RawSocket s, const void *buffer, const int len, const int params,
00236 const SockAddrInet *remote, const int remsize )
00237 {
00238 return ::sendto( s, static_cast<const char *>(buffer), len, params,
00239 reinterpret_cast<const SockAddr *>(remote), remsize );
00240 }
00241
00242 static int recvfrom(const RawSocket s, void *buffer, const int len, const int params,
00243 SockAddrInet *remote, int *remsize )
00244 {
00245 return ::recvfrom( s, static_cast<char *>(buffer), len, params,
00246 reinterpret_cast<SockAddr *>(remote), remsize );
00247 }
00248
00249 static void shutdown( const RawSocket s ) {
00250 setBlocking( s );
00251 ::shutdown( s, SD_SEND );
00252 }
00253
00254
00258 static void sleep ( const int msecs ) { Sleep( msecs ); }
00259
00260 static NetPort hostToNetPort( const NetPort data ) { return ::htons( data ) ; }
00261 static NetAddr hostToNetAddr( const NetAddr data ) { return ::htonl( data ) ; }
00262 static NetPort netToHostPort( const NetPort data ) { return ::ntohs( data ) ; }
00263 static NetAddr netToHostAddr( const NetAddr data ) { return ::ntohl( data ) ; }
00264
00265 static MSECS timeOfDay();
00266
00267 };
00268
00270 typedef Net_WSA Net;
00271
00272 };
00273
00274
00275
00276 #endif
00277
00278
00279