00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "stdafx.h"
00037 #include "SocketBase.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040 #include "OSManager.h"
00041 #include "GenericCriticalSection.h"
00042 #include "LibConfig.h"
00043
00044 #include <memory>
00045
00046 #ifdef _MEMORY_DEBUG
00047 #define new DEBUG_NEW
00048 #define malloc DEBUG_MALLOC
00049 static char THIS_FILE[] = __FILE__;
00050 #endif
00051
00052 KOMODIA_NAMESPACE_START
00053
00054
00055 BOOL CSocketBase::m_bMultiThreaded=FALSE;
00056
00057
00058 BOOL CSocketBase::m_bInitialized=FALSE;
00059
00060
00061 int CSocketBase::m_ulNumberOfThreads=0;
00062
00063
00064 CGenericCriticalSection* CSocketBase::m_pCSection=NULL;
00065
00066
00067 CSocketBase* CSocketBase::m_pShutdownClass=NULL;
00068
00069
00070 CSocketBase::DNSMap CSocketBase::m_aDNSMap;
00071
00072
00073 CGenericCriticalSection* CSocketBase::m_pCSectionDNS=NULL;
00074
00075
00076 #define THREAD_TIMEOUT 10000
00077
00078 #define CSocketBase_Class "CSocketBase"
00079
00080 CSocketBase::CSocketBase() : CErrorHandler()
00081 {
00082 try
00083 {
00084
00085 SetName(CSocketBase_Class);
00086 }
00087 ERROR_HANDLER("CSocketBase")
00088 }
00089
00090 CSocketBase::CSocketBase(const CSocketBase& rBase) : CErrorHandler(rBase)
00091 {
00092 try
00093 {
00094
00095 SetName(CSocketBase_Class);
00096 }
00097 ERROR_HANDLER("CSocketBase")
00098 }
00099
00100 CSocketBase::~CSocketBase()
00101 {
00102 }
00103
00104 void CSocketBase::SetLastError(const std::string& rMethod) const
00105 {
00106 try
00107 {
00108 #ifdef WIN32
00109
00110 m_iLastError=WSAGetLastError();
00111 #else
00112 m_iLastError=errno();
00113 #endif
00114
00115
00116 if (m_iLastError)
00117 ReportError(rMethod,
00118 "Through SetLastError",
00119 m_iLastError);
00120 }
00121 ERROR_HANDLER("SetLastError")
00122 }
00123
00124 void CSocketBase::SetLastError(const std::string& rMethod,
00125 int iErrorCode)const
00126 {
00127 try
00128 {
00129
00130 m_iLastError=iErrorCode;
00131
00132
00133 if (m_iLastError)
00134 ReportError(rMethod,
00135 "Through SetLastError",
00136 m_iLastError);
00137 }
00138 ERROR_HANDLER("SetLastError")
00139 }
00140
00141 int CSocketBase::GetLastError()const
00142 {
00143 return m_iLastError;
00144 }
00145
00146 BOOL CSocketBase::InitializeSockets(BOOL bMultiThreaded,
00147 unsigned long ulNumberOfThreads)
00148 {
00149
00150 if (m_bInitialized)
00151 {
00152
00153 ReportStaticError(CSocketBase_Class,"InitializeSockets","Already initialized!");
00154
00155
00156 return TRUE;
00157 }
00158
00159
00160 if (ulNumberOfThreads>CLibConfig::GetInstance().GetMaxThreads())
00161 {
00162
00163 ReportStaticError(CSocketBase_Class,"InitializeSockets","Too many threads!");
00164
00165
00166 return FALSE;
00167 }
00168
00169
00170 if (bMultiThreaded &&
00171 !ulNumberOfThreads)
00172 {
00173
00174 ReportStaticError(CSocketBase_Class,"InitializeSockets","Didn't receive any threads!");
00175
00176
00177 return FALSE;
00178 }
00179
00180 try
00181 {
00182
00183 WORD wVersionRequested;
00184 wVersionRequested=MAKEWORD(2,2);
00185
00186
00187 WSADATA wsaData;
00188 int iErr;
00189 iErr=WSAStartup(wVersionRequested,
00190 &wsaData);
00191
00192
00193 if (iErr!=0)
00194
00195
00196 return FALSE;
00197
00198
00199
00200
00201
00202
00203
00204 if (LOBYTE(wsaData.wVersion)!=2 ||
00205 HIBYTE(wsaData.wVersion)!=2)
00206 {
00207
00208
00209 WSACleanup();
00210
00211
00212 return FALSE;
00213 }
00214
00215
00216 m_bMultiThreaded=bMultiThreaded;
00217 m_ulNumberOfThreads=ulNumberOfThreads;
00218
00219
00220 m_pCSection=COSManager::CreateCriticalSection();
00221 m_pCSectionDNS=COSManager::CreateCriticalSection();
00222
00223
00224 m_bInitialized=TRUE;
00225
00226 return TRUE;
00227 }
00228 ERROR_HANDLER_STATIC_RETURN(CSocketBase_Class,"InitializeSockets",FALSE)
00229 }
00230
00231 BOOL CSocketBase::ShutdownSockets()
00232 {
00233
00234 if (!m_bInitialized)
00235 return TRUE;
00236
00237 try
00238 {
00239
00240 delete m_pCSection;
00241 m_pCSection=NULL;
00242
00243
00244 delete m_pCSectionDNS;
00245 m_pCSectionDNS=NULL;
00246
00247
00248 m_aDNSMap.clear();
00249
00250
00251 if (m_pShutdownClass)
00252 {
00253
00254 m_pShutdownClass->NotifyShutdown();
00255
00256
00257 delete m_pShutdownClass;
00258 m_pShutdownClass=NULL;
00259 }
00260
00261
00262 m_bInitialized=FALSE;
00263
00264 if (WSACleanup()==GetErrorCode())
00265 return FALSE;
00266
00267
00268 return TRUE;
00269 }
00270 ERROR_HANDLER_STATIC_RETURN(CSocketBase_Class,"ShutdownSockets",FALSE)
00271 }
00272
00273 void CSocketBase::NotifyShutdown()
00274 {
00275 }
00276
00277 void CSocketBase::RegisterShutdown(CSocketBase* pBase)
00278 {
00279 try
00280 {
00281
00282 if (m_pShutdownClass)
00283 delete m_pShutdownClass;
00284
00285
00286 m_pShutdownClass=pBase;
00287 }
00288 ERROR_HANDLER("RegisterShutdown")
00289 }
00290
00291 std::string CSocketBase::LongToStdString(unsigned long ulAddr)
00292 {
00293 try
00294 {
00295
00296 in_addr addr;
00297
00298
00299 addr.S_un.S_addr=ulAddr;
00300
00301
00302 CCriticalAutoRelease aRelease(m_pCSection);
00303
00304
00305 return inet_ntoa(addr);
00306 }
00307 ERROR_HANDLER_STATIC_RETURN(CSocketBase_Class,"LongToStdString","0.0.0.0")
00308 }
00309
00310 char FAR * CSocketBase::LongToString(unsigned long ulAddr)
00311 {
00312 try
00313 {
00314
00315 in_addr addr;
00316
00317
00318 addr.S_un.S_addr=ulAddr;
00319
00320
00321 CCriticalAutoRelease aRelease(m_pCSection);
00322
00323
00324 return inet_ntoa(addr);
00325 }
00326 ERROR_HANDLER_STATIC_RETURN(CSocketBase_Class,"LongToString",NULL)
00327 }
00328
00329 BOOL CSocketBase::IsMultiThreaded()
00330 {
00331 return m_bMultiThreaded;
00332 }
00333
00334 unsigned long CSocketBase::GetNumberOfThreads()
00335 {
00336 return m_ulNumberOfThreads;
00337 }
00338
00339 BOOL CSocketBase::IsInitialized()
00340 {
00341 return m_bInitialized;
00342 }
00343
00344 unsigned long CSocketBase::StringToLong(const std::string& rAddress)
00345 {
00346
00347 unsigned long ulAddress;
00348 ulAddress=inet_addr(rAddress.c_str());
00349
00350
00351 if (ulAddress!=INADDR_NONE)
00352 return ulAddress;
00353 else
00354
00355 return ResolveDNS(rAddress);
00356 }
00357
00358 int CSocketBase::GetSystemLastError()
00359 {
00360 return WSAGetLastError();
00361 }
00362
00363 CGenericCriticalSection* CSocketBase::GetGlobalCriticalSection()
00364 {
00365 return m_pCSection;
00366 }
00367
00368 int CSocketBase::GetErrorCode()
00369 {
00370 return SOCKET_ERROR;
00371 }
00372
00373 BOOL CSocketBase::ValidAddress(const std::string& rAddress)
00374 {
00375 try
00376 {
00377 return inet_addr(rAddress.c_str())!=INADDR_NONE;
00378 }
00379 ERROR_HANDLER_STATIC_RETURN(CSocketBase_Class,"ValidAddress",FALSE)
00380 }
00381
00382 sockaddr_in CSocketBase::InternalResolveDNS(const std::string& rAddress)
00383 {
00384
00385 sockaddr_in aAddr;
00386 memset(&aAddr,0,sizeof(aAddr));
00387
00388 try
00389 {
00390
00391 CCriticalAutoRelease aRelease(m_pCSectionDNS);
00392
00393
00394 DNSMap::iterator aIterator;
00395 aIterator=m_aDNSMap.find(rAddress);
00396
00397
00398 if (aIterator!=m_aDNSMap.end())
00399
00400 return aIterator->second;
00401 else
00402 {
00403
00404 aRelease.Exit();
00405
00406
00407 hostent* pData;
00408 pData=gethostbyname(rAddress.c_str());
00409
00410
00411 if (pData)
00412 {
00413
00414 memcpy(&aAddr.sin_addr,
00415 pData->h_addr,
00416 pData->h_length);
00417
00418
00419 aRelease.Enter();
00420
00421
00422 m_aDNSMap.insert(DNSMap::value_type(rAddress,aAddr));
00423 }
00424
00425 return aAddr;
00426 }
00427 }
00428 ERROR_HANDLER_STATIC_RETURN(CSocketBase_Class,"InternalResolveDNS",aAddr)
00429 }
00430
00431 unsigned long CSocketBase::ResolveDNS(const std::string& rAddress)
00432 {
00433 try
00434 {
00435
00436 sockaddr_in aAddr;
00437 aAddr=InternalResolveDNS(rAddress.c_str());
00438
00439
00440 if (aAddr.sin_addr.S_un.S_addr==0)
00441
00442 return 0;
00443 else
00444 return aAddr.sin_addr.S_un.S_addr;
00445 }
00446 ERROR_HANDLER_STATIC_RETURN(CSocketBase_Class,"ResolveDNS",0)
00447 }
00448
00449 KOMODIA_NAMESPACE_END