/*//=============================================================== << WINSOCK BASE >> PRGM : B4nFter FILE : WINSOCKBASE.HPP DESC : ¸ðµç ¿ø¼Ó Ŭ·¡½ºµéÀÇ ±âº» Ŭ·¡½º INIT BUILT DATE : 2005. 04. 28 LAST BUILT DATE : 2005. 04. 28 Copyright¨Ï 2002~2009 B4nFter (b4nfter@gmail.com) and Co-Writers. All Rights Reserved. *///=============================================================== #pragma once /////////////////////////////////////////////////////////////////// // INCLUDE /////////////////////////////////////////////////////////////////// #include "ERRORFORMAT.H" #include "SYSBASEBASE.H" #include "IPV4.HPP" #include /////////////////////////////////////////////////////////////////// // DEFINE /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // DECLARATION /////////////////////////////////////////////////////////////////// //*--------------------------------------------------------------- // TYPE : CLASS // NAME : CWinsockBase //*--------------------------------------------------------------- // DESC : Winsock Base Socket Class // PRGM : B4nFter //*--------------------------------------------------------------- class CWinsockBase { public: static enum { EV_ERROR_NONE, // ¿¡·¯ - none EV_ERROR_SYSTEM, // ¿¡·¯ - system EV_ERROR_LOGIC // ¿¡·¯ - logic }; typedef std::list TP_IPLIST; typedef TP_IPLIST::iterator TP_IPLIST_ITR; public: inline CWinsockBase(); inline virtual ~CWinsockBase(); // P.S.> ¸í¹éÇÑ ¿À·ù, Â÷ÈÄ ¼öÁ¤ (*.h, *.cpp ·Î ºÐ¸® ÇÊ¿ä) INT GetErrorCode() { return m_ErrorFormat.GetErrorCode(); } inline static BOOL GetPhysicalAddress(LPBYTE lpbtPhysicalAddress); inline static BOOL GetHostByName(LPCSTR lpszHostName, ULONG& uIpAddress); inline static INT GetLocalIpAddressList(TP_IPLIST& pLocalIpAddressList); inline static INT GetSockOpt(SOCKET pSocket, INT pLevel, INT pOptName, PCHAR pOptVal, PINT pOptLen); inline static INT SetSockOpt(SOCKET pSocket, INT pLevel, INT pOptName, PCHAR pOptVal, INT pOptLen); private: inline BOOL Initialize(); inline VOID Finalize(); protected: SOCKADDR_IN m_stSockAddr; WSADATA m_stWsaData; CErrorFormat m_ErrorFormat; }; /////////////////////////////////////////////////////////////////// // IMPLEMENTATION /////////////////////////////////////////////////////////////////// //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CWinsockBase::CWinsockBase //*--------------------------------------------------------------- // DESC : »ý¼ºÀÚ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- CWinsockBase::CWinsockBase() { Initialize(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CWinsockBase::~CWinsockBase //*--------------------------------------------------------------- // DESC : ¼Ò¸êÀÚ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- CWinsockBase::~CWinsockBase() { Finalize(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CWinsockBase::Initialize //*--------------------------------------------------------------- // DESC : °´Ã¼ °ü·Ã ÀÚ¿øµéÀ» ÃʱâÈ­ // PARM : N/A // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter //*--------------------------------------------------------------- BOOL CWinsockBase::Initialize() { INT iErrNo = 0; iErrNo = ::WSAStartup(MAKEWORD(2,2), & m_stWsaData); if (iErrNo) { switch (iErrNo) { case WSASYSNOTREADY : case WSAVERNOTSUPPORTED : case WSAEINPROGRESS : case WSAEPROCLIM : case WSAEFAULT : { TCHAR szText[128] = { _T('\0'), }; SNPRINTF(MODE_DBG_EX(szText, COUNT_OF(szText)), COUNT_OF(szText), _T("CWinsockBase::Initialize() - WSAStartup() error : %d"), iErrNo); m_ErrorFormat.Write(szText); return FALSE; } } } return TRUE; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CWinsockBase::Finalize //*--------------------------------------------------------------- // DESC : °´Ã¼ °ü·Ã ÀÚ¿øµéÀ» ÇØÁ¦ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- VOID CWinsockBase::Finalize() { ::WSACleanup(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CWinsockBase::GetPhysicalAddress //*--------------------------------------------------------------- // DESC : È£½ºÆ®ÀÇ ³×Æ®¿öÅ© ¹°¸®ÁÖ¼Ò (MAC) ¸¦ ¾òÀ½ // PARM : 1 . lpbtPhysicalAddress - È£½ºÆ®ÀÇ ³×Æ®¿öÅ© ¹°¸®ÁÖ¼Ò (MAC) ¸¦ ¹ÞÀ» BYTE¹è¿­ÀÇ Æ÷ÀÎÅÍ (ÁÖÀÇ!!> . ÃÖ¼Ò 6¹ÙÀÌÆ® ÀÌ»ó) // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter //*--------------------------------------------------------------- BOOL CWinsockBase::GetPhysicalAddress(LPBYTE lpbtPhysicalAddress) { UUID stUuid; INT iRetVal = ::UuidCreateSequential(&stUuid); // Ask OS to create UUID if (iRetVal != RPC_S_OK) { BASE_TRACE(_T("iRetVal != RPC_S_OK : %d - CWinsockBase::GetPhysicalAddress()"), iRetVal); return FALSE; } for (INT iCount = 2 ; iCount<8 ; ++iCount) { // UUID ÀÇ ¸â¹ö Data4 ÀÇ 2 ~ 7 ¹ÙÀÌÆ® »çÀ̰¡ MAC ÁÖ¼ÒÀÌ´Ù. lpbtPhysicalAddress[iCount-2] = stUuid.Data4[iCount]; } return TRUE; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CWinsockBase::GetHostByName //*--------------------------------------------------------------- // DESC : IP À̸§ÀÌ dotted decimal Çü½ÄÀÌ ¾Æ´Ñ domain name Çü½ÄÀÏ ¶§ À̸¦ Á¤¼öÇüÅÂÀÇ IP4 ÁÖ¼Ò·Î º¯°æÇØ ÁÜ // PARM : 1 . lpszHostName - domain name Çü½ÄÀÇ È£½ºÆ® ÁÖ¼Ò // 2 . uIpAddress - Á¤¼öÇü½ÄÀÇ IP4 È£½ºÆ® ÁÖ¼Ò¸¦ ¹ÝȯÇÒ º¯¼ö // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter /* EXAM : SOCKADDR_IN stSockAddr; ... ... stSockAddr.sin_addr.s_addr = ::inet_addr(ipszAddress); if (INADDR_NONE == stSockAddr.sin_addr.s_addr) { if (TRUE == CWinsockBase::GetHostByName(ipszAddress, stSockAddr.sin_addr.s_addr)) { // ¹ø¿ª¼º°ø } else { // ¿¡·¯ } } */ //*--------------------------------------------------------------- BOOL CWinsockBase::GetHostByName(LPCSTR lpszHostName, ULONG& uIpAddress) { LPHOSTENT lpstHostent; lpstHostent = ::gethostbyname(lpszHostName); if (lpstHostent) { uIpAddress = ((LPIN_ADDR)lpstHostent->h_addr)->s_addr; } else { return FALSE; } return TRUE; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CWinsockBase::GetLocalIpAddressList //*--------------------------------------------------------------- // DESC : ·ÎÄÃÈ£½ºÆ®ÀÇ IPÁÖ¼Ò ¸®½ºÆ®¸¦ ¾òÀ½ // PARM : 1 . pLocalIpAddressList - IPÁÖ¼Ò ¸ñ·ÏÀ» ¹Þ¾Æ¿Ã ¸®½ºÆ® °´Ã¼ // RETV : ·ÎÄÃÈ£½ºÆ®ÀÇ IPÁÖ¼ÒÀÇ °³¼ö ¹Ýȯ // PRGM : B4nFter //*--------------------------------------------------------------- INT CWinsockBase::GetLocalIpAddressList(TP_IPLIST& pLocalIpAddressList) { CHAR szHostName[128]; ::gethostname(szHostName, sizeof(szHostName)); LPHOSTENT lpstHostent = ::gethostbyname(szHostName); // !!! ¿¹¿Ü¹ß»ý - 0x000006C5 (1733) űװ¡ Ʋ¸³´Ï´Ù. if (!lpstHostent) { return 0; } LPIN_ADDR lpstInAddr; std::string stTempIpAddress; switch (lpstHostent->h_addrtype) { case AF_INET : while(NULL != (lpstInAddr = ((LPIN_ADDR)*lpstHostent->h_addr_list++))) { stTempIpAddress = ::inet_ntoa(*lpstInAddr); pLocalIpAddressList.push_back(stTempIpAddress); } break; } return (INT)pLocalIpAddressList.size(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CSessionBase::GetSockOpt //*--------------------------------------------------------------- // DESC : º» ¼¼¼ÇÀÇ ¼ÒÄÏ¿¡ ´ëÇÑ Æ¯Á¤ ¿É¼ÇÀ» ¾òÀ½ // PARM : 1 . pSocket - ¿É¼ÇÀ» ÁöÁ¤ÇÒ ¼ÒÄÏ // 2 . pLevel - ¼ÒÄÏ ¿É¼ÇÀÌ À§Ä¡ÇÑ ·¹º§ /* IPPROTO_IP IPPROTO_IPV6 IPPROTO_TCP IPPROTO_UDP SOL_SOCKET SOL_IRLMP */ // 3 . pOptName - °ªÀ» ¾ò°íÀÚ ÇÏ´Â ¼ÒÄÏ ¿É¼ÇÀÇ À̸§ (pLevel ¸¶´Ù °¢±â ´Ù¸£¹Ç·Î Âü°í) // 4 . pOptVal - ¿äûÇÑ ¿É¼Ç °ªÀ» ¾ò¾î¿Ã ¹öÆÛ // 5 . pOptLen - ¿äûÇÑ ¿É¼Ç °ªÀ» ¾ò¾î¿Ã ¹öÆÛÀÇ Å©±â // RETV : NOERROR - ¼º°ø / ±×¿Ü - ½ÇÆÐ (::WSAGetLastError() °ª) // PRGM : B4nFter // P.S.> // - ¾Æ·¡ MSDN URL ¿¡¼­ getsockopt() ¿É¼Ç Âü°íÇÒ °Í // http://msdn.microsoft.com/en-us/library/ms738544.aspx //*--------------------------------------------------------------- INT CWinsockBase::GetSockOpt(SOCKET pSocket, INT pLevel, INT pOptName, PCHAR pOptVal, PINT pOptLen) { INT iRetVal = ::getsockopt(pSocket, pLevel, pOptName, pOptVal, pOptLen); if (SOCKET_ERROR == iRetVal) { BASE_RETURN(::WSAGetLastError()); } return NOERROR; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CSessionBase::SetSockOpt //*--------------------------------------------------------------- // DESC : º» ¼¼¼ÇÀÇ ¼ÒÄÏ¿¡ ƯÁ¤ ¿É¼ÇÀ» ÁöÁ¤ // PARM : 1 . pSocket - ¿É¼ÇÀ» ÁöÁ¤ÇÒ ¼ÒÄÏ // 2 . pLevel - ¼ÒÄÏ ¿É¼ÇÀÌ À§Ä¡ÇÑ ·¹º§ /* IPPROTO_IP IPPROTO_IPV6 IPPROTO_TCP IPPROTO_UDP SOL_SOCKET SOL_IRLMP */ // 3 . pOptName - °ªÀ» ÁöÁ¤ÇϰíÀÚ ÇÏ´Â ¼ÒÄÏ ¿É¼ÇÀÇ À̸§ (pLevel ¸¶´Ù °¢±â ´Ù¸£¹Ç·Î Âü°í) // 4 . pOptVal - ÁöÁ¤ÇÒ ¿É¼Ç °ªÀÌ À§Ä¡ÇÑ ¹öÆÛ // 5 . pOptLen - ÁöÁ¤ÇÒ ¿É¼Ç °ªÀÌ À§Ä¡ÇÑ ¹öÆÛÀÇ Å©±â // RETV : NOERROR - ¼º°ø / ±×¿Ü - ½ÇÆÐ (::WSAGetLastError() °ª) // PRGM : B4nFter // P.S.> // - ¾Æ·¡ MSDN URL ¿¡¼­ setsockopt() ¿É¼Ç Âü°íÇÒ °Í // http://msdn.microsoft.com/en-us/library/ms740476.aspx //*--------------------------------------------------------------- INT CWinsockBase::SetSockOpt(SOCKET pSocket, INT pLevel, INT pOptName, PCHAR pOptVal, INT pOptLen) { INT iRetVal = ::setsockopt(pSocket, pLevel, pOptName, pOptVal, pOptLen); if (SOCKET_ERROR == iRetVal) { BASE_RETURN(::WSAGetLastError()); } return NOERROR; }