DragonNest/Server/ServiceMonitorEx/Source/EventSelectTcpClientSession.inl

764 lines
23 KiB
Text
Raw Normal View History

2024-12-19 09:48:26 +08:00
///////////////////////////////////////////////////////////////////
// INCLUDE
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// IMPLEMENTATION
///////////////////////////////////////////////////////////////////
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::CEventSelectTcpClientSession
//*---------------------------------------------------------------
// DESC : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
CEventSelectTcpClientSession<TSESSION>::CEventSelectTcpClientSession()
{
Initialize();
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::~CEventSelectTcpClientSession
//*---------------------------------------------------------------
// DESC : <20>Ҹ<EFBFBD><D2B8><EFBFBD>
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
CEventSelectTcpClientSession<TSESSION>::~CEventSelectTcpClientSession()
{
Finalize();
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::Initialize
//*---------------------------------------------------------------
// DESC : <20><>ü <20><><EFBFBD><EFBFBD> <20>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ
// PARM : N/A
// RETV : TRUE - <20><><EFBFBD><EFBFBD> / FALSE - <20><><EFBFBD><EFBFBD>
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
BOOL CEventSelectTcpClientSession<TSESSION>::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 : <20><>ü <20><><EFBFBD><EFBFBD> <20>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
VOID CEventSelectTcpClientSession<TSESSION>::Finalize()
{
m_RecvIoBuffer.Finalize();
m_SendIoBuffer.Finalize();
// m_Lock.Close();
TP_SUPER::Close();
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::CreateBuffer
//*---------------------------------------------------------------
// DESC : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>/<2F><><EFBFBD>ſ<EFBFBD> <20><><EFBFBD>۸<EFBFBD> <20><><EFBFBD><EFBFBD>
// PARM : 1 . iRecvBufferSize - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ſ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><C5A9>
// 2 . iSendBufferSize - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۽ſ<DBBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><C5A9>
// RETV : TRUE - <20><><EFBFBD><EFBFBD> / FALSE - <20><><EFBFBD><EFBFBD>
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
BOOL CEventSelectTcpClientSession<TSESSION>::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 : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ſ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD>
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
VOID CEventSelectTcpClientSession<TSESSION>::DeleteBuffer()
{
m_RecvIoBuffer.Finalize();
m_SendIoBuffer.Finalize();
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::Reset
//*---------------------------------------------------------------
// DESC : <20><>ü<EFBFBD><C3BC><EFBFBD><EFBFBD> <20>ڿ<EFBFBD> <20>ʱ<EFBFBD>ȭ
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
VOID CEventSelectTcpClientSession<TSESSION>::Reset()
{
// m_lpParam = NULL;
::memset(&m_stRemoteSockAddrIn, 0, sizeof(m_stRemoteSockAddrIn));
TP_SUPER::Reset();
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::CreateSocket
//*---------------------------------------------------------------
// DESC : <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD>
// PARM : N/A
// RETV : TRUE - <20><><EFBFBD><EFBFBD> / FALSE - <20><><EFBFBD><EFBFBD>
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
BOOL CEventSelectTcpClientSession<TSESSION>::CreateSocket()
{
if (m_sckThis != INVALID_SOCKET) {
// miss
BASE_RETURN(FALSE);
}
m_sckThis = ::socket(AF_INET, SOCK_STREAM, 0);
if (m_sckThis == INVALID_SOCKET) {
// <20><><EFBFBD><EFBFBD>
BASE_RETURN(FALSE);
}
return TRUE;
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::CloseSocket
//*---------------------------------------------------------------
// DESC : <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD>
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
VOID CEventSelectTcpClientSession<TSESSION>::CloseSocket()
{
SAFE_CLOSESOCKET(m_sckThis);
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::Connect
//*---------------------------------------------------------------
// DESC : Ư<><C6AF> TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TCP <20><><EFBFBD><EFBFBD>
// PARM : 1 . lpszIpAddress - Ư<><C6AF> TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP<49>ּ<EFBFBD> (IP<49>ּ<EFBFBD> Ȥ<><C8A4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD>)
// 2 . wPortNumber - Ư<><C6AF> TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE>ȣ
// RETV : TRUE - <20><><EFBFBD><EFBFBD> / FALSE - <20><><EFBFBD><EFBFBD>
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
BOOL CEventSelectTcpClientSession<TSESSION>::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 : Ư<><C6AF> TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TCP <20><><EFBFBD><EFBFBD>
// PARM : 1 . uIpAddress - Ư<><C6AF> TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP<49>ּ<EFBFBD> (<28><>Ʈ<EFBFBD><C6AE>ũ <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>)
// 2 . wPortNumber - Ư<><C6AF> TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE>ȣ
// RETV : TRUE - <20><><EFBFBD><EFBFBD> / FALSE - <20><><EFBFBD><EFBFBD>
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
BOOL CEventSelectTcpClientSession<TSESSION>::Connect(ULONG uIpAddress, WORD wPortNumber)
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ
CLockAuto AutoLock(&m_Lock);
if (!m_bIsActivated) {
return FALSE;
}
if (!CreateSocket()) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(0, _T("!CreateSocket() - CEventSelectTcpClientSession::Connect()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// DisconnectNoLock();
return FALSE;
}
if (0 <= GetRecvSckBufferSize()) {
INT iRecvSckBufferSize = GetRecvSckBufferSize();
INT iRetVal = SetSockOpt(SOL_SOCKET, SO_RCVBUF, ((PCHAR)&iRecvSckBufferSize), sizeof(iRecvSckBufferSize));
if (NOERROR != iRetVal) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(iRetVal, _T("!SetSockOpt() - CEventSelectTcpClientSession::Connect() : SO_RCVBUF"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// DisconnectNoLock();
BASE_RETURN(FALSE);
}
}
if (0 <= GetSendSckBufferSize()) {
INT iSendSckBufferSize = GetSendSckBufferSize();
INT iRetVal = SetSockOpt(SOL_SOCKET, SO_SNDBUF, ((PCHAR)&iSendSckBufferSize), sizeof(iSendSckBufferSize));
if (NOERROR != iRetVal) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(iRetVal, _T("!SetSockOpt() - CEventSelectTcpClientSession::Connect() : SO_SNDBUF"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// DisconnectNoLock();
BASE_RETURN(FALSE);
}
}
if (m_RecvIoBuffer.GetBufferSize() <= 0 || m_SendIoBuffer.GetBufferSize() <= 0) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(0, _T("m_RecvIoBuffer.GetBufferSize() <= 0 (%d) || m_SendIoBuffer.GetBufferSize() <= 0 - CEventSelectTcpClientSession::Connect()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
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))) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::Connect()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
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) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::Connect()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
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) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::Connect()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DisconnectNoLock();
return FALSE;
}
}
m_stRemoteSockAddrIn = stSockAddrIn;
SetEventHandle(hEvent);
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۾<EFBFBD><DBBE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD><E8BFAD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
m_lpEventSelectTcpClient->RegisterSession(this);
return TRUE;
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::Disconnect
//*---------------------------------------------------------------
// DESC : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
VOID CEventSelectTcpClientSession<TSESSION>::Disconnect()
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ
CLockAuto AutoLock(&m_Lock);
DisconnectNoLock();
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::DisconnectNoLock
//*---------------------------------------------------------------
// DESC : Ư<><C6AF> TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TCP <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>ȭ <20><><EFBFBD><EFBFBD>)
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
VOID CEventSelectTcpClientSession<TSESSION>::DisconnectNoLock()
{
// if (!m_bIsActivated) {
// return;
// }
if (m_sckThis == INVALID_SOCKET) {
return;
}
if (WSA_INVALID_EVENT != m_hEvent) {
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۾<EFBFBD><DBBE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD><E8BFAD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
m_lpEventSelectTcpClient->UnregisterSession(this);
::WSACloseEvent(m_hEvent);
m_hEvent = WSA_INVALID_EVENT;
}
// <20>ڵ<EFBFBD><DAB5><EFBFBD> <20><><EFBFBD>ŵ<EFBFBD> <20>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
CloseSocket();
Reset();
m_RecvIoBuffer.Reset();
m_SendIoBuffer.Reset();
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::RecvData
//*---------------------------------------------------------------
// DESC : Ư<><C6AF> TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// PARM : N/A
// RETV : TRUE - <20><><EFBFBD><EFBFBD> / FALSE - <20><><EFBFBD><EFBFBD>
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
BOOL CEventSelectTcpClientSession<TSESSION>::RecvData()
{
// <20><><EFBFBD><EFBFBD> <20><>ȣ <20><> <20><> <20>Լ<EFBFBD><D4BC><EFBFBD> ȣ<><C8A3><EFBFBD>ϴ<EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20>̷<EFBFBD><CCB7><EFBFBD><EFBFBD><EFBFBD>
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) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::RecvData()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DisconnectNoLock();
return FALSE;
}
else {
return TRUE;
}
}
}
if (!uIoBytes) {
// !!1 . gracefully closed - FD_CLOSE <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><20><> <20><><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ??
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DisconnectNoLock();
return TRUE;
}
m_RecvIoBuffer.AddBufferTailPtr(uIoBytes);
if (m_RecvIoBuffer.GetBufferTailPtr() > m_RecvIoBuffer.GetBufferSize()) {
// <20≯<EFBFBD> <20><><EFBFBD><EFBFBD> ũ<><20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> WSARecv() <20><> ȣ<><C8A3><EFBFBD>ϹǷ<CFB9> <20>̷<EFBFBD> <20><><EFBFBD><20>߻<EFBFBD><DFBB>Ҹ<EFBFBD><D2B8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȥ<><C8A4> <20>߻<EFBFBD><DFBB>ϴ<EFBFBD><CFB4><EFBFBD> üũ<C3BC><C5A9> <20><><EFBFBD>ƾ<EFBFBD> <20>Ѵ<EFBFBD>.
m_RecvIoBuffer.SetBufferTailPtr(m_RecvIoBuffer.GetBufferSize());
BASE_TRACE(_T("m_RecvIoBuffer.GetBufferTailPtr() > m_RecvIoBuffer.GetBufferSize() - CEventSelectTcpClientSession::RecvData()"));
}
// <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20>޾<EFBFBD><DEBE><EFBFBD>
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) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(0, _T("FALSE == m_lpfnRecvNotifyProc() - CEventSelectTcpClientSession::RecvData()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DisconnectNoLock();
return FALSE;
}
}
MoveLeftRecvBufferToHead();
return TRUE;
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::SendData
//*---------------------------------------------------------------
// DESC : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ư<><C6AF> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۽<EFBFBD>
// PARM : 1 . lpbtBuffer - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 2 . iBufferSize - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><C5A9>
// 3 . bDoLock - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EBBFA9>
// RETV : TRUE - <20><><EFBFBD><EFBFBD> / FALSE - <20><><EFBFBD><EFBFBD>
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
BOOL CEventSelectTcpClientSession<TSESSION>::SendData(LPBYTE lpbtBuffer, INT iBufferSize, BOOL bDoLock)
{
if (!lpbtBuffer || iBufferSize <= 0) {
return FALSE;
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ
CCriticalSection* aLock = (bDoLock)?(GetLock()):(NULL);
CLockAuto AutoLock(aLock);
INT iLeftDataLen = SendLeftData();
if (iLeftDataLen == SOCKET_ERROR) {
// <20><><EFBFBD><EFBFBD> - SendLeftData() <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3> <20>Ͽ<EFBFBD><CFBF><EFBFBD>
return FALSE;
}
if (!m_bIsActivated) {
return FALSE;
}
if (!iLeftDataLen) {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD>. <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
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) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::SendData()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DisconnectNoLock();
return FALSE;
}
else {
// ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִٸ<D6B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
iBufferHeadPtr += uIoBytes;
if (iBufferHeadPtr >= iBufferTailPtr) {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>´<EFBFBD>.
return TRUE;
}
else {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>. <20><><EFBFBD>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>۽Ź<DBBD><C5B9>ۿ<EFBFBD> <20>ִ´<D6B4>.
MoveLeftSendBufferToHead();
if (m_SendIoBuffer.GetFreeBufferSize() < iBufferTailPtr - iBufferHeadPtr) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(0, _T("m_SendIoBuffer.GetFreeBufferSize() < iBufferTailPtr - iBufferHeadPtr - CEventSelectTcpClientSession::SendData()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
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) {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>´<EFBFBD>.
return TRUE;
}
}
}
else {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD>ۿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
if (m_SendIoBuffer.GetFreeBufferSize() < iBufferSize) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(0, _T("m_SendIoBuffer.GetFreeBufferSize() < iBufferSize - CEventSelectTcpClientSession::SendData()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DisconnectNoLock();
return FALSE;
}
::memcpy(m_SendIoBuffer.GetBuffer() + m_SendIoBuffer.GetBufferHeadPtr(), lpbtBuffer, iBufferSize);
m_SendIoBuffer.AddBufferTailPtr(iBufferSize);
if (SendLeftData() == SOCKET_ERROR) {
// <20><><EFBFBD><EFBFBD> - SendLeftData() <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3> <20>Ͽ<EFBFBD><CFBF><EFBFBD>
return FALSE;
}
}
return TRUE;
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::SendLeftData
//*---------------------------------------------------------------
// DESC : <20><><EFBFBD><EFBFBD> <20>۽<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ۿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> üũ<C3BC>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۽<EFBFBD>
// PARM : N/A
// RETV : 0 - <20><><EFBFBD><EFBFBD> / 0 <20>̻<EFBFBD> - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><C5A9> / SOCKET_ERROR - <20><><EFBFBD><EFBFBD>
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
INT CEventSelectTcpClientSession<TSESSION>::SendLeftData()
{
// <20><><EFBFBD><EFBFBD> <20><>ȣ <20><> <20><> <20>Լ<EFBFBD><D4BC><EFBFBD> ȣ<><C8A3><EFBFBD>ϴ<EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20>̷<EFBFBD><CCB7><EFBFBD><EFBFBD><EFBFBD>
if (!m_SendIoBuffer.GetBufferTailPtr()) {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߿<EFBFBD><DFBF>ϰ<EFBFBD> üũ<C3BC><C5A9> <20><>ƾ<EFBFBD>̹Ƿ<CCB9> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ʿ<EFBFBD> <20><>ġ
return 0;
}
if (m_sckThis == INVALID_SOCKET) {
return SOCKET_ERROR;
}
if (m_SendIoBuffer.GetBufferTailPtr() < 0) {
// <20>̷<EFBFBD> <20><><EFBFBD><20>߻<EFBFBD><DFBB>ϴ<EFBFBD><CFB4><EFBFBD> Ȯ<><C8AE>
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(0, _T("m_SendIoBuffer.GetBufferTailPtr() < 0 - CEventSelectTcpClientSession::SendLeftData()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DisconnectNoLock();
return SOCKET_ERROR;
}
if (m_SendIoBuffer.GetBufferTailPtr() > m_SendIoBuffer.GetBufferHeadPtr()) {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20>ִ<EFBFBD>.
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) {
// <20><><EFBFBD><EFBFBD>
SaveErrorMessage(::GetLastError(), _T(" - CEventSelectTcpClientSession::SendLeftData()"));
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DisconnectNoLock();
return SOCKET_ERROR;
}
else {
// ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִٸ<D6B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
m_SendIoBuffer.AddBufferHeadPtr(uIoBytes);
if (m_SendIoBuffer.GetBufferHeadPtr() >= m_SendIoBuffer.GetBufferTailPtr()) {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>´<EFBFBD>.
m_SendIoBuffer.Reset();
return 0;
}
else {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>.
MoveLeftSendBufferToHead();
return m_SendIoBuffer.GetBufferTailPtr();
}
}
}
m_SendIoBuffer.AddBufferHeadPtr(uIoBytes);
if (m_SendIoBuffer.GetBufferHeadPtr() >= m_SendIoBuffer.GetBufferTailPtr()) {
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>´<EFBFBD>.
m_SendIoBuffer.Reset();
return 0;
}
}
}
else {
// <20>̷<EFBFBD> <20><><EFBFBD>°<EFBFBD> <20>߻<EFBFBD><DFBB><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ<C3BC><C5A9> <20><><EFBFBD>ƾ<EFBFBD> <20>Ѵ<EFBFBD>.
m_SendIoBuffer.Reset();
}
return 0;
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::MoveLeftRecvBufferToHead
//*---------------------------------------------------------------
// DESC : <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5><EFBFBD>Ŵ
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
VOID CEventSelectTcpClientSession<TSESSION>::MoveLeftRecvBufferToHead()
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ<EFBFBD><C8AD> ȣ<><C8A3><EFBFBD>ϴ<EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20>̷<EFBFBD><CCB7><EFBFBD> <20><>
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() <20><> <20><>Ȳ<EFBFBD><C8B2> <20>߻<EFBFBD><DFBB>Ѵٸ<D1B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_RecvIoBuffer.Reset();
}
}
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::MoveLeftSendBufferToHead
//*---------------------------------------------------------------
// DESC : <20>۽<EFBFBD> <20>۾<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5><EFBFBD>Ŵ
// PARM : N/A
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
VOID CEventSelectTcpClientSession<TSESSION>::MoveLeftSendBufferToHead()
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ<EFBFBD><C8AD> ȣ<><C8A3><EFBFBD>ϴ<EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20>̷<EFBFBD><CCB7><EFBFBD> <20><>
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() <20><> <20><>Ȳ<EFBFBD><C8B2> <20>߻<EFBFBD><DFBB>Ѵٸ<D1B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_SendIoBuffer.Reset();
}
}
}
//*---------------------------------------------------------------
// TYPE : FUNCTION
// NAME : CEventSelectTcpClientSession::SaveErrorMessage
//*---------------------------------------------------------------
// DESC : Ŭ<><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>޽<EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20>˷<EFBFBD><CBB7><EFBFBD>
// PARM : 1 . iErrorCode - <20>ý<EFBFBD><C3BD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
// 2 . lpszErrorMessage - <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>޽<EFBFBD><DEBD><EFBFBD>
// RETV : N/A
// PRGM : B4nFter
//*---------------------------------------------------------------
template<class TSESSION>
VOID CEventSelectTcpClientSession<TSESSION>::SaveErrorMessage(INT iErrorCode, LPCTSTR lpszErrorMessage)
{
if (m_lpfnBaseNotifyProc) {
m_lpfnBaseNotifyProc(EV_NBN_ERROR, this, m_ErrorFormat.Write(iErrorCode, lpszErrorMessage), m_lpBaseNotifyProcParam);
}
}