/////////////////////////////////////////////////////////////////// // INCLUDE /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // IMPLEMENTATION /////////////////////////////////////////////////////////////////// //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::CEventSelectTcpClientSession //*--------------------------------------------------------------- // DESC : »ý¼ºÀÚ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template CEventSelectTcpClientSession::CEventSelectTcpClientSession() { Initialize(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::~CEventSelectTcpClientSession //*--------------------------------------------------------------- // DESC : ¼Ò¸êÀÚ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template CEventSelectTcpClientSession::~CEventSelectTcpClientSession() { Finalize(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::Initialize //*--------------------------------------------------------------- // DESC : °´Ã¼ °ü·Ã ÀÚ¿øµéÀ» ÃʱâÈ­ // PARM : N/A // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter //*--------------------------------------------------------------- template BOOL CEventSelectTcpClientSession::Initialize() { if (NOERROR != TP_SUPER::Open()) { BASE_RETURN(FALSE); } m_sckThis = INVALID_SOCKET; m_lpfnBaseNotifyProc = NULL; m_lpfnRecvNotifyProc = NULL; m_lpBaseNotifyProcParam = NULL; m_lpRecvNotifyProcParam = NULL; m_hEvent = WSA_INVALID_EVENT; // m_lpParam = NULL; m_lpEventSelectTcpClient = NULL; m_bIsActivated = FALSE; Reset(); // if (NOERROR != m_Lock.Open()) { // BASE_RETURN(FALSE); // } return TRUE; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::Finalize //*--------------------------------------------------------------- // DESC : °´Ã¼ °ü·Ã ÀÚ¿øµéÀ» ÇØÁ¦ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template VOID CEventSelectTcpClientSession::Finalize() { m_RecvIoBuffer.Finalize(); m_SendIoBuffer.Finalize(); // m_Lock.Close(); TP_SUPER::Close(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::CreateBuffer //*--------------------------------------------------------------- // DESC : µ¥ÀÌÅÍ ¼Û/¼ö½Å¿ë ¹öÆÛ¸¦ »ý¼º // PARM : 1 . iRecvBufferSize - µ¥ÀÌÅÍ ¼ö½Å¿ë ¹öÆÛÀÇ Å©±â // 2 . iSendBufferSize - µ¥ÀÌÅÍ ¼Û½Å¿ë ¹öÆÛÀÇ Å©±â // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter //*--------------------------------------------------------------- template BOOL CEventSelectTcpClientSession::CreateBuffer(INT iRecvBufferSize, INT iSendBufferSize) { if (iRecvBufferSize <= 0 || iSendBufferSize <= 0) { return FALSE; } if (m_RecvIoBuffer.GetBufferSize() > 0) { m_RecvIoBuffer.Finalize(); } if (m_SendIoBuffer.GetBufferSize() > 0) { m_SendIoBuffer.Finalize(); } if (m_RecvIoBuffer.Initialize(iRecvBufferSize) == FALSE) { BASE_RETURN(FALSE); } if (m_SendIoBuffer.Initialize(iSendBufferSize) == FALSE) { BASE_RETURN(FALSE); } return TRUE; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::DeleteBuffer //*--------------------------------------------------------------- // DESC : µ¥ÀÌÅÍ ¼ö½Å¿ë ¹öÆÛÀÚ¿øÀ» ÇØÁ¦ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template VOID CEventSelectTcpClientSession::DeleteBuffer() { m_RecvIoBuffer.Finalize(); m_SendIoBuffer.Finalize(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::Reset //*--------------------------------------------------------------- // DESC : °´Ã¼°ü·Ã ÀÚ¿ø ÃʱâÈ­ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template VOID CEventSelectTcpClientSession::Reset() { // m_lpParam = NULL; ::memset(&m_stRemoteSockAddrIn, 0, sizeof(m_stRemoteSockAddrIn)); TP_SUPER::Reset(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::CreateSocket //*--------------------------------------------------------------- // DESC : ¼ÒÄÏ ±â¼úÀÚ¸¦ »ý¼º // PARM : N/A // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter //*--------------------------------------------------------------- template BOOL CEventSelectTcpClientSession::CreateSocket() { if (m_sckThis != INVALID_SOCKET) { // miss BASE_RETURN(FALSE); } m_sckThis = ::socket(AF_INET, SOCK_STREAM, 0); if (m_sckThis == INVALID_SOCKET) { // ¿¡·¯ BASE_RETURN(FALSE); } return TRUE; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::CloseSocket //*--------------------------------------------------------------- // DESC : ¼ÒÄÏ ±â¼úÀÚ¸¦ ´ÝÀ½ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template VOID CEventSelectTcpClientSession::CloseSocket() { SAFE_CLOSESOCKET(m_sckThis); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::Connect //*--------------------------------------------------------------- // DESC : ƯÁ¤ TCP ¼­¹ö·Î TCP ¿¬°á // PARM : 1 . lpszIpAddress - ƯÁ¤ TCP ¼­¹öÀÇ IPÁÖ¼Ò (IPÁÖ¼Ò È¤Àº µµ¸ÞÀÎÀ̸§) // 2 . wPortNumber - ƯÁ¤ TCP ¼­¹öÀÇ Æ÷Æ®¹øÈ£ // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter //*--------------------------------------------------------------- template BOOL CEventSelectTcpClientSession::Connect(LPCSTR lpszIpAddress, WORD wPortNumber) { ULONG uIpAddress = ::inet_addr(lpszIpAddress); if (INADDR_NONE == uIpAddress) { if (FALSE == CWinsockBase::GetHostByName(lpszIpAddress, uIpAddress)) { BASE_RETURN(FALSE); } } return Connect(uIpAddress, wPortNumber); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::Connect //*--------------------------------------------------------------- // DESC : ƯÁ¤ TCP ¼­¹ö·Î TCP ¿¬°á // PARM : 1 . uIpAddress - ƯÁ¤ TCP ¼­¹öÀÇ IPÁÖ¼Ò (³×Æ®¿öÅ© ¹ÙÀÌÆ® ¿À´õ) // 2 . wPortNumber - ƯÁ¤ TCP ¼­¹öÀÇ Æ÷Æ®¹øÈ£ // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter //*--------------------------------------------------------------- template BOOL CEventSelectTcpClientSession::Connect(ULONG uIpAddress, WORD wPortNumber) { // ¼¼¼Ç µ¿±âÈ­ CLockAuto AutoLock(&m_Lock); if (!m_bIsActivated) { return FALSE; } if (!CreateSocket()) { // ¿¡·¯ SaveErrorMessage(0, _T("!CreateSocket() - CEventSelectTcpClientSession::Connect()")); // ¼¼¼Ç Á¾·á // DisconnectNoLock(); return FALSE; } if (0 <= GetRecvSckBufferSize()) { INT iRecvSckBufferSize = GetRecvSckBufferSize(); INT iRetVal = SetSockOpt(SOL_SOCKET, SO_RCVBUF, ((PCHAR)&iRecvSckBufferSize), sizeof(iRecvSckBufferSize)); if (NOERROR != iRetVal) { // ¿¡·¯ SaveErrorMessage(iRetVal, _T("!SetSockOpt() - CEventSelectTcpClientSession::Connect() : SO_RCVBUF")); // ¼¼¼Ç Á¾·á // DisconnectNoLock(); BASE_RETURN(FALSE); } } if (0 <= GetSendSckBufferSize()) { INT iSendSckBufferSize = GetSendSckBufferSize(); INT iRetVal = SetSockOpt(SOL_SOCKET, SO_SNDBUF, ((PCHAR)&iSendSckBufferSize), sizeof(iSendSckBufferSize)); if (NOERROR != iRetVal) { // ¿¡·¯ SaveErrorMessage(iRetVal, _T("!SetSockOpt() - CEventSelectTcpClientSession::Connect() : SO_SNDBUF")); // ¼¼¼Ç Á¾·á // DisconnectNoLock(); BASE_RETURN(FALSE); } } if (m_RecvIoBuffer.GetBufferSize() <= 0 || m_SendIoBuffer.GetBufferSize() <= 0) { // ¿¡·¯ SaveErrorMessage(0, _T("m_RecvIoBuffer.GetBufferSize() <= 0 (%d) || m_SendIoBuffer.GetBufferSize() <= 0 - CEventSelectTcpClientSession::Connect()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return FALSE; } m_RecvIoBuffer.Reset(); m_SendIoBuffer.Reset(); LINGER stLinger; stLinger.l_onoff = 1; stLinger.l_linger = 0; if (SOCKET_ERROR == ::setsockopt(m_sckThis, SOL_SOCKET, SO_LINGER, (CHAR*)&stLinger, sizeof(stLinger))) { // ¿¡·¯ SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::Connect()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return FALSE; } SOCKADDR_IN stSockAddrIn; stSockAddrIn.sin_family = AF_INET; stSockAddrIn.sin_port = ::htons(wPortNumber); stSockAddrIn.sin_addr.s_addr = uIpAddress; HANDLE hEvent = ::WSACreateEvent(); if (hEvent == WSA_INVALID_EVENT) { BASE_TRACE(_T("hEvent == WSA_INVALID_EVENT (%d) - CEventSelectTcpClientSession::Connect()"), ::WSAGetLastError()); return FALSE; } INT iErrNo = ::WSAEventSelect(m_sckThis, hEvent, FD_CONNECT | FD_CLOSE); if (iErrNo == SOCKET_ERROR) { // ¿¡·¯ SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::Connect()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return FALSE; } iErrNo = ::WSAConnect(m_sckThis, (LPSOCKADDR)&stSockAddrIn, sizeof(stSockAddrIn), NULL, NULL, NULL, NULL); if (iErrNo == SOCKET_ERROR) { iErrNo = ::WSAGetLastError(); if (iErrNo != WSA_IO_PENDING && iErrNo != WSAEWOULDBLOCK) { // ¿¡·¯ SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::Connect()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return FALSE; } } m_stRemoteSockAddrIn = stSockAddrIn; SetEventHandle(hEvent); // ÀÌ ¼¼¼ÇÀ» ÀÛ¾÷½º·¹µåÀÇ ÇÚµé¹è¿­¿¡ µî·ÏÇÑ´Ù. m_lpEventSelectTcpClient->RegisterSession(this); return TRUE; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::Disconnect //*--------------------------------------------------------------- // DESC : ¼¼¼ÇÀÇ ¿¬°áÀ» ÇØÁ¦ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template VOID CEventSelectTcpClientSession::Disconnect() { // ¼¼¼Ç µ¿±âÈ­ CLockAuto AutoLock(&m_Lock); DisconnectNoLock(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::DisconnectNoLock //*--------------------------------------------------------------- // DESC : ƯÁ¤ TCP ¼­¹ö¿ÍÀÇ TCP ¿¬°á ÇØÁ¦ (µ¿±âÈ­ ¾øÀ½) // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template VOID CEventSelectTcpClientSession::DisconnectNoLock() { // if (!m_bIsActivated) { // return; // } if (m_sckThis == INVALID_SOCKET) { return; } if (WSA_INVALID_EVENT != m_hEvent) { // ÀÌ ¼¼¼ÇÀ» ÀÛ¾÷½º·¹µåÀÇ ÇÚµé¹è¿­¿¡¼­ Á¦°ÅÇÑ´Ù. m_lpEventSelectTcpClient->UnregisterSession(this); ::WSACloseEvent(m_hEvent); m_hEvent = WSA_INVALID_EVENT; } // ÇÚµéÀÌ Á¦°ÅµÈ ÈÄ¿¡ ¼ÒÄÏÀÌ ´ÝÇô¾ß ÇÑ´Ù. CloseSocket(); Reset(); m_RecvIoBuffer.Reset(); m_SendIoBuffer.Reset(); } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::RecvData //*--------------------------------------------------------------- // DESC : ƯÁ¤ TCP ¼­¹ö·Î ºÎÅÍ µ¥ÀÌÅÍ ¼ö½Å // PARM : N/A // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter //*--------------------------------------------------------------- template BOOL CEventSelectTcpClientSession::RecvData() { // ¼¼¼Ç º¸È£ ¡æ ÀÌ ÇÔ¼ö¸¦ È£ÃâÇÏ´Â ÂÊ¿¡¼­ ÀÌ·ç¾îÁü if (m_sckThis == INVALID_SOCKET) { return FALSE; } if (!m_bIsActivated) { return FALSE; } WSABUF stWsaBuf; stWsaBuf.buf = (CHAR*)m_RecvIoBuffer.GetBuffer() + m_RecvIoBuffer.GetBufferTailPtr(); stWsaBuf.len = m_RecvIoBuffer.GetBufferSize() - m_RecvIoBuffer.GetBufferTailPtr(); ULONG uIoBytes; ULONG uFlag = 0; // important to set 0 !!! { CLockAuto AutoLock(&m_Lock); INT iErrNo = ::WSARecv(m_sckThis, &stWsaBuf, 1, &uIoBytes, &uFlag, NULL, NULL); if (iErrNo == SOCKET_ERROR) { iErrNo = ::WSAGetLastError(); if (iErrNo != WSA_IO_PENDING && iErrNo != WSAEWOULDBLOCK) { // ¿¡·¯ SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::RecvData()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return FALSE; } else { return TRUE; } } } if (!uIoBytes) { // !!1 . gracefully closed - FD_CLOSE ·Î °¥ °ÍÀ¸¹Ç·Î ¿©±â¿¡ ¿Ã °¡´É¼ºÀº °ÅÀÇ ¾øÀ½ ?? // ¼¼¼Ç Á¾·á DisconnectNoLock(); return TRUE; } m_RecvIoBuffer.AddBufferTailPtr(uIoBytes); if (m_RecvIoBuffer.GetBufferTailPtr() > m_RecvIoBuffer.GetBufferSize()) { // ¹Ì¸® ¹ÞÀ» Å©±â¸¦ °è»êÇϰí WSARecv() ¸¦ È£ÃâÇϹǷΠÀÌ·± °æ¿ì°¡ ¹ß»ýÇÒ¸®´Â ¾ø°ÚÁö¸¸ Ȥ½Ã ¹ß»ýÇÏ´ÂÁö Ã¼Å©ÇØ º¸¾Æ¾ß ÇÑ´Ù. m_RecvIoBuffer.SetBufferTailPtr(m_RecvIoBuffer.GetBufferSize()); BASE_TRACE(_T("m_RecvIoBuffer.GetBufferTailPtr() > m_RecvIoBuffer.GetBufferSize() - CEventSelectTcpClientSession::RecvData()")); } // µ¥ÀÌÅ͸¦ ¹Þ¾ÒÀ½ if (m_lpfnRecvNotifyProc) { BOOL bRetVal = m_lpfnRecvNotifyProc( this, (CHAR*)m_RecvIoBuffer.GetBuffer() + m_RecvIoBuffer.GetBufferHeadPtr(), m_RecvIoBuffer.RefBufferHeadPtr(), m_RecvIoBuffer.GetBufferTailPtr() - m_RecvIoBuffer.GetBufferHeadPtr(), m_RecvIoBuffer.GetBufferSize(), m_lpRecvNotifyProcParam, GetRemoteSockAddrIn().sin_addr, GetRemotePortNumberN() ); if (!bRetVal) { // ¿¡·¯ SaveErrorMessage(0, _T("FALSE == m_lpfnRecvNotifyProc() - CEventSelectTcpClientSession::RecvData()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return FALSE; } } MoveLeftRecvBufferToHead(); return TRUE; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::SendData //*--------------------------------------------------------------- // DESC : ¿¬°áµÈ ÇØ´ç ¼¼¼ÇÀ¸·Î ƯÁ¤ µ¥ÀÌÅÍ ¼Û½Å // PARM : 1 . lpbtBuffer - Àü¼ÛÇÒ µ¥ÀÌÅÍ ¹öÆÛ Æ÷ÀÎÅÍ // 2 . iBufferSize - Àü¼ÛÇÒ µ¥ÀÌÅÍÀÇ Å©±â // 3 . bDoLock - Àá±Ý »ç¿ë¿©ºÎ // RETV : TRUE - ¼º°ø / FALSE - ½ÇÆÐ // PRGM : B4nFter //*--------------------------------------------------------------- template BOOL CEventSelectTcpClientSession::SendData(LPBYTE lpbtBuffer, INT iBufferSize, BOOL bDoLock) { if (!lpbtBuffer || iBufferSize <= 0) { return FALSE; } // ¼¼¼Ç µ¿±âÈ­ CCriticalSection* aLock = (bDoLock)?(GetLock()):(NULL); CLockAuto AutoLock(aLock); INT iLeftDataLen = SendLeftData(); if (iLeftDataLen == SOCKET_ERROR) { // ¿¡·¯ - SendLeftData() ³»ºÎ¿¡¼­ Á¾·áó¸® ÇÏ¿´À½ return FALSE; } if (!m_bIsActivated) { return FALSE; } if (!iLeftDataLen) { // º¸³¾ ³²Àº µ¥ÀÌÅͰ¡ ¾øÀ½. ±×³É º¸³½´Ù. WSABUF stWsaBuf; ULONG uIoBytes; INT iErrNo; INT iBufferHeadPtr = 0, iBufferTailPtr= iBufferSize; BOOL bInfinite = TRUE; while(bInfinite) { stWsaBuf.buf = (CHAR*)lpbtBuffer + iBufferHeadPtr; stWsaBuf.len = iBufferTailPtr - iBufferHeadPtr; iErrNo = ::WSASend(m_sckThis, &stWsaBuf, 1, &uIoBytes, 0, NULL, NULL); if (iErrNo == SOCKET_ERROR) { iErrNo = ::WSAGetLastError(); if (iErrNo != WSA_IO_PENDING && iErrNo != WSAEWOULDBLOCK) { // ¿¡·¯ SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::SendData()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return FALSE; } else { // 󸮰¡ Áö¿¬µÉ °æ¿ì µ¥ÀÌÅͰ¡ ³²¾ÆÀÖ´Ù¸é ´ÙÀ½¿¡ º¸³»¾ß ÇÑ´Ù. iBufferHeadPtr += uIoBytes; if (iBufferHeadPtr >= iBufferTailPtr) { // ¸ðµÎ º¸³Â´Ù. return TRUE; } else { // º¸³¾ µ¥ÀÌÅͰ¡ ÀÌÁ÷ ³²¾ÆÀÖ´Ù. Â÷ÈÄ¿¡ º¸³»±â À§ÇØ ¼Û½Å¹öÆÛ¿¡ ³Ö´Â´Ù. MoveLeftSendBufferToHead(); if (m_SendIoBuffer.GetFreeBufferSize() < iBufferTailPtr - iBufferHeadPtr) { // ¿¡·¯ SaveErrorMessage(0, _T("m_SendIoBuffer.GetFreeBufferSize() < iBufferTailPtr - iBufferHeadPtr - CEventSelectTcpClientSession::SendData()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return FALSE; } ::memcpy(m_SendIoBuffer.GetBuffer() + m_SendIoBuffer.GetBufferHeadPtr(), lpbtBuffer + iBufferHeadPtr, iBufferTailPtr - iBufferHeadPtr); m_SendIoBuffer.AddBufferTailPtr(iBufferTailPtr - iBufferHeadPtr); return TRUE; } } } iBufferHeadPtr += uIoBytes; if (iBufferHeadPtr >= iBufferTailPtr) { // ¸ðµÎ º¸³Â´Ù. return TRUE; } } } else { // º¸³¾ ³²Àº µ¥ÀÌÅͰ¡ ÀÖÀ½. ¹öÆÛ¿¡ µ¥ÀÌÅ͸¦ º¹»çÇÏ°í º¸³½´Ù. if (m_SendIoBuffer.GetFreeBufferSize() < iBufferSize) { // ¿¡·¯ SaveErrorMessage(0, _T("m_SendIoBuffer.GetFreeBufferSize() < iBufferSize - CEventSelectTcpClientSession::SendData()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return FALSE; } ::memcpy(m_SendIoBuffer.GetBuffer() + m_SendIoBuffer.GetBufferHeadPtr(), lpbtBuffer, iBufferSize); m_SendIoBuffer.AddBufferTailPtr(iBufferSize); if (SendLeftData() == SOCKET_ERROR) { // ¿¡·¯ - SendLeftData() ³»ºÎ¿¡¼­ Á¾·áó¸® ÇÏ¿´À½ return FALSE; } } return TRUE; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::SendLeftData //*--------------------------------------------------------------- // DESC : ÀÌÀü ¼Û½Å ÈÄ ³²Àº ¹öÆÛ¿¡ ³²Àº µ¥ÀÌÅͰ¡ ÀÖ´ÂÁö üũÇÏ¿© ³ª¸ÓÁöµµ ¼Û½Å // PARM : N/A // RETV : 0 - ¼º°ø / 0 ÀÌ»ó - ³²Àº µ¥ÀÌÅÍ Å©±â / SOCKET_ERROR - ¿¡·¯ // PRGM : B4nFter //*--------------------------------------------------------------- template INT CEventSelectTcpClientSession::SendLeftData() { // ¼¼¼Ç º¸È£ ¡æ ÀÌ ÇÔ¼ö¸¦ È£ÃâÇÏ´Â ÂÊ¿¡¼­ ÀÌ·ç¾îÁü if (!m_SendIoBuffer.GetBufferTailPtr()) { // °¡Àå ¸¹ÀÌ Áß¿äÇÏ°Ô Ã¼Å©µÉ ·çƾÀ̹ǷΠ°¡Àå ¾ÕÂÊ¿¡ ¹èÄ¡ return 0; } if (m_sckThis == INVALID_SOCKET) { return SOCKET_ERROR; } if (m_SendIoBuffer.GetBufferTailPtr() < 0) { // ÀÌ·± °æ¿ì°¡ ¹ß»ýÇÏ´ÂÁö È®ÀÎ // ¿¡·¯ SaveErrorMessage(0, _T("m_SendIoBuffer.GetBufferTailPtr() < 0 - CEventSelectTcpClientSession::SendLeftData()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return SOCKET_ERROR; } if (m_SendIoBuffer.GetBufferTailPtr() > m_SendIoBuffer.GetBufferHeadPtr()) { // º¸³¾ µ¥ÀÌÅͰ¡ ÀÖ´Ù. WSABUF stWsaBuf; ULONG uIoBytes; INT iErrNo; BOOL bInfinite = TRUE; while(bInfinite) { stWsaBuf.buf = (CHAR*)m_SendIoBuffer.GetBuffer() + m_SendIoBuffer.GetBufferHeadPtr(); stWsaBuf.len = m_SendIoBuffer.GetBufferTailPtr() - m_SendIoBuffer.GetBufferHeadPtr(); iErrNo = ::WSASend(m_sckThis, &stWsaBuf, 1, &uIoBytes, 0, NULL, NULL); if (iErrNo == SOCKET_ERROR) { iErrNo = ::WSAGetLastError(); if (iErrNo != WSA_IO_PENDING && iErrNo != WSAEWOULDBLOCK) { // ¿¡·¯ SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::SendLeftData()")); // ¼¼¼Ç Á¾·á DisconnectNoLock(); return SOCKET_ERROR; } else { // 󸮰¡ Áö¿¬µÉ °æ¿ì µ¥ÀÌÅͰ¡ ³²¾ÆÀÖ´Ù¸é ´ÙÀ½¿¡ º¸³»¾ß ÇÑ´Ù. m_SendIoBuffer.AddBufferHeadPtr(uIoBytes); if (m_SendIoBuffer.GetBufferHeadPtr() >= m_SendIoBuffer.GetBufferTailPtr()) { // ¸ðµÎ º¸³Â´Ù. m_SendIoBuffer.Reset(); return 0; } else { // º¸³¾ µ¥ÀÌÅͰ¡ ÀÌÁ÷ ³²¾ÆÀÖ´Ù. MoveLeftSendBufferToHead(); return m_SendIoBuffer.GetBufferTailPtr(); } } } m_SendIoBuffer.AddBufferHeadPtr(uIoBytes); if (m_SendIoBuffer.GetBufferHeadPtr() >= m_SendIoBuffer.GetBufferTailPtr()) { // ¸ðµÎ º¸³Â´Ù. m_SendIoBuffer.Reset(); return 0; } } } else { // ÀÌ·± »óŰ¡ ¹ß»ýÇÒ ÀÏÀº °ÅÀÇ ¾ø°ÚÁö¸¸ Ã¼Å©ÇØ º¸¾Æ¾ß ÇÑ´Ù. m_SendIoBuffer.Reset(); } return 0; } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::MoveLeftRecvBufferToHead //*--------------------------------------------------------------- // DESC : ¼ö½Å ÀÛ¾÷ ÈÄ ³²Àº µ¥ÀÌÅ͸¦ ¹öÆÛÀÇ ¸Ç ¾ÕÂÊÀ¸·Î À̵¿½ÃÅ´ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template VOID CEventSelectTcpClientSession::MoveLeftRecvBufferToHead() { // ¼¼¼Ç µ¿±âÈ­´Â È£ÃâÇÏ´Â ÂÊ¿¡¼­ ÀÌ·ç¾î Áü if (m_RecvIoBuffer.GetBuffer() && m_RecvIoBuffer.GetBufferHeadPtr() > 0) { if (m_RecvIoBuffer.GetBufferTailPtr() > m_RecvIoBuffer.GetBufferHeadPtr()) { ::memmove(m_RecvIoBuffer.GetBuffer(), m_RecvIoBuffer.GetBuffer() + m_RecvIoBuffer.GetBufferHeadPtr(), m_RecvIoBuffer.GetBufferTailPtr() - m_RecvIoBuffer.GetBufferHeadPtr()); m_RecvIoBuffer.AddBufferTailPtr(-m_RecvIoBuffer.GetBufferHeadPtr()); m_RecvIoBuffer.SetBufferHeadPtr(0); } else { // m_RecvIoBuffer.GetBufferTailPtr() < m_RecvIoBuffer.GetBufferHeadPtr() ÀÇ »óȲÀÌ ¹ß»ýÇÑ´Ù¸é ¿¡·¯ÀÓ m_RecvIoBuffer.Reset(); } } } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::MoveLeftSendBufferToHead //*--------------------------------------------------------------- // DESC : ¼Û½Å ÀÛ¾÷ ÈÄ ³²Àº µ¥ÀÌÅ͸¦ ¹öÆÛÀÇ ¸Ç ¾ÕÂÊÀ¸·Î À̵¿½ÃÅ´ // PARM : N/A // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template VOID CEventSelectTcpClientSession::MoveLeftSendBufferToHead() { // ¼¼¼Ç µ¿±âÈ­´Â È£ÃâÇÏ´Â ÂÊ¿¡¼­ ÀÌ·ç¾î Áü if (m_SendIoBuffer.GetBuffer() && m_SendIoBuffer.GetBufferHeadPtr() > 0) { if (m_SendIoBuffer.GetBufferTailPtr() > m_SendIoBuffer.GetBufferHeadPtr()) { ::memmove(m_SendIoBuffer.GetBuffer(), m_SendIoBuffer.GetBuffer() + m_SendIoBuffer.GetBufferHeadPtr(), m_SendIoBuffer.GetBufferTailPtr() - m_SendIoBuffer.GetBufferHeadPtr()); m_SendIoBuffer.AddBufferTailPtr(-m_SendIoBuffer.GetBufferHeadPtr()); m_SendIoBuffer.SetBufferHeadPtr(0); } else { // m_SendIoBuffer.GetBufferTailPtr() < m_SendIoBuffer.GetBufferHeadPtr() ÀÇ »óȲÀÌ ¹ß»ýÇÑ´Ù¸é ¿¡·¯ÀÓ m_SendIoBuffer.Reset(); } } } //*--------------------------------------------------------------- // TYPE : FUNCTION // NAME : CEventSelectTcpClientSession::SaveErrorMessage //*--------------------------------------------------------------- // DESC : Ŭ·¡½º ³»ºÎ¿¡ ¿¡·¯¸Þ½ÃÁö¸¦ ÀúÀå, »ç¿ëÀÚ¿¡°Ô ¾Ë·ÁÁÜ // PARM : 1 . iErrorCode - ½Ã½ºÅÛ ¿¡·¯ÄÚµå // 2 . lpszErrorMessage - Ãß°¡ÀûÀÎ ¿¡·¯¸Þ½ÃÁö // RETV : N/A // PRGM : B4nFter //*--------------------------------------------------------------- template VOID CEventSelectTcpClientSession::SaveErrorMessage(INT iErrorCode, LPCTSTR lpszErrorMessage) { if (m_lpfnBaseNotifyProc) { m_lpfnBaseNotifyProc(EV_NBN_ERROR, this, m_ErrorFormat.Write(iErrorCode, lpszErrorMessage), m_lpBaseNotifyProcParam); } }