123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- //---------------------------------------------------------------------------
- #pragma hdrstop
- #include "ClientSessionF.h"
- #include "PacketHandllingF.h"
- #include "VMSCommLibF.h"
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- TClientSession::TClientSession(SOCKET ASock, SOCKADDR_IN* ASockAddr)
- {
- Create(ASock, ASockAddr);
- }
- //---------------------------------------------------------------------------
- TClientSession::TClientSession()
- {
- FSocket = INVALID_SOCKET;
- FState = eSS_none;
- FIpAddress = "";
- FPort = 0;
- Init();
- }
- //---------------------------------------------------------------------------
- void TClientSession::Create(SOCKET ASock, SOCKADDR_IN* ASockAddr)
- {
- FSocket = ASock;
- FState = eSS_OnConnect;
- memcpy(&FSocketAddr, ASockAddr, sizeof(SOCKADDR_IN));
- FIpAddress.printf("%s", inet_ntoa(FSocketAddr.sin_addr));
- FPort = ntohs(FSocketAddr.sin_port);
- Init();
- }
- //---------------------------------------------------------------------------
- void TClientSession::Init()
- {
- FConnected = false;
- FRecvIdx = 0;
- FSendIdx = 0;
- FPacketLen = 0;
- FPacketSent = 0;
- FPacketPtr = NULL;
- FCDSCtlr = NULL;
- FCDSLogCtlr = NULL;
- FCloseTick = 0;
- FChkRecvTO = false;
- FTmrSend = Now();
- FTmrRecv = Now();
- }
- //---------------------------------------------------------------------------
- TClientSession::~TClientSession()
- {
- }
- //---------------------------------------------------------------------------
- int TClientSession::SocketError()
- {
- FLastErr = WSAGetLastError();
- LPVOID lpMsgBuf = NULL;
- try
- {
- try
- {
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- FLastErr,
- //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL
- );
- char *pData = (char*)lpMsgBuf;
- if (strlen(pData) > 2)
- {
- pData[strlen(pData)-2] = 0x00;
- pData[strlen(pData)-1] = 0x00;
- }
- FErrorString.printf("%s", pData);
- }
- catch(Exception &e)
- {
- FErrorString.printf("%s, %s", AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
- }
- }
- __finally
- {
- if (lpMsgBuf) LocalFree(lpMsgBuf);
- lpMsgBuf = NULL;
- }
- return FLastErr;
- }
- //---------------------------------------------------------------------------
- bool TClientSession::OnConnect()
- {
- FConnected = true;
- if (!CheckLoginClient())
- {
- Disconnect();
- return false;
- }
- // 소켓을 넌블러킹으로 바꾸고
- u_long arg = 1 ;
- ioctlsocket(FSocket, FIONBIO, &arg) ;
- /// nagle 알고리즘 끄기
- int opt = 1 ;
- setsockopt(FSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&opt, sizeof(int));
- FTmrConn = Now();
- return true;
- }
- //---------------------------------------------------------------------------
- int TClientSession::GetFreeSpaceSize()
- {
- return (SESSION_RECV_BUFFER - FRecvIdx);
- }
- //---------------------------------------------------------------------------
- char* TClientSession::GetBuffer()
- {
- return (char*)FRecvBuff+FRecvIdx;
- }
- //---------------------------------------------------------------------------
- void TClientSession::RecvBuffCommit(int ARecvLen)
- {
- FRecvIdx += ARecvLen;
- }
- //---------------------------------------------------------------------------
- void TClientSession::Disconnect()
- {
- OnDisconnected();
- if (!IsConnected) return;
- // 즉각 해제
- LINGER linger;
- linger.l_onoff = 1;
- linger.l_linger = 0;
- // no TCP TIME_WAIT
- if (SOCKET_ERROR == setsockopt(FSocket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(LINGER)))
- {
- // printf_s("[DEBUG] setsockopt linger option error: %d\n", GetLastError());
- // return;
- }
- closesocket(FSocket);
- //FSocket = INVALID_SOCKET; ==> 여기서 초기화 하면 ClientSessionManager에서 삭제할때 오류발생 소켓을 키로 사용함
- FConnected = false ;
- FState = eSS_OnDisconnect;
- FCDSCtlr = NULL;
- FCloseTick = 0;
- FState = eSS_none;
- FSocket = INVALID_SOCKET;
- }
- //---------------------------------------------------------------------------
- void TClientSession::OnWriteComplete(int ASendLen, int AReqLen)
- {
- /// 보내기 완료한 데이터는 버퍼에서 제거
- if (FSendIdx >= ASendLen) FSendIdx -= ASendLen;
- }
- //---------------------------------------------------------------------------
- bool TClientSession::SendRequest(char *AData, int ADataLen)
- {
- if (!IsConnected)
- {
- MERROR("+SVR Session SendRequest: %s[%d], already closed", FIpAddress.c_str(), FSocket);
- Disconnect();
- return false;
- }
- if (ADataLen > (SESSION_SEND_BUFFER - FSendIdx))
- {
- /// 버퍼 용량 부족인 경우는 끊어버림
- MERROR("+SVR Session SendRequest: %s[%d], Send Buffer Overflow, will be closed.", FIpAddress.c_str(), FSocket);
- Disconnect();
- return false;
- }
- FPacketLen = ADataLen;
- FPacketSent= 0;
- FPacketPtr = FSendBuff+FSendIdx;
- memcpy(FSendBuff+FSendIdx, AData, ADataLen);
- FSendIdx += ADataLen;
- return true;
- }
- //---------------------------------------------------------------------------
- bool TClientSession::SendFlush()
- {
- if (!IsConnected)
- {
- MERROR("+SVR Session SendFlush: %s[%d], already closed", FIpAddress.c_str(), FSocket);
- Disconnect();
- return false;
- }
- /// 보낼 데이터가 없으면 그냥 리턴
- if (FSendIdx == 0)
- return true;
- DWORD sendbytes = 0;
- DWORD flags = 0;
- int nLeft = FSendIdx;
- char *buf = (char*)FSendBuff;//+FSendIdx;
- int nSendedBytes = send(FSocket, buf, nLeft, 0);
- if (nSendedBytes <= 0)
- {
- MERROR("+SVR Session SendFlush: %s[%d]: send error: %d, %d", FIpAddress.c_str(), FSocket, nSendedBytes, WSAGetLastError());
- Disconnect();
- return false;
- }
- MDEBUG("+SVR Sessionclient send: %s[%d], %6d bytes send", FIpAddress.c_str(), FSocket, nSendedBytes);
- OnWriteComplete(nSendedBytes, nLeft);
- FPacketSent += nSendedBytes;
- if (FPacketSent >= FPacketLen)
- {
- OnWrite(FPacketPtr, FPacketLen);
- FPacketSent -= FPacketLen;
- FPacketPtr = FSendBuff + FPacketSent;
- }
- return true;
- }
- //---------------------------------------------------------------------------
- bool TClientSession::SendFlushComplete()
- {
- while (true)
- {
- if (!SendFlush())
- {
- return false;
- }
- if (FSendIdx == 0)
- {
- break;
- }
- Sleep(10);
- }
- Sleep(20);
- return true;
- }
- //---------------------------------------------------------------------------
- char* TClientSession::GetPacket()
- {
- return FRecvBuff;
- }
- //---------------------------------------------------------------------------
- bool TClientSession::ResetPacket(int APktLen)
- {
- if (APktLen > FRecvIdx) return false;
- FRecvIdx -= APktLen;
- if (FRecvIdx > 0)
- {
- memmove(FRecvBuff, FRecvBuff+APktLen, FRecvIdx);
- //FRecvIdx = 0;
- }
- return true;
- }
- //---------------------------------------------------------------------------
- int TClientSession::LogData(char *ASndRcv, BYTE *AData, int ALen)
- {
- // Hex Data 파일에 저장하고
- // FrmCommLog 창에 뿌리는거
- TCDSCtlr* pCDSCtlr = FCDSLogCtlr;
- if (!pCDSCtlr)
- {
- ITSLog->LogData(ASndRcv, AData, ALen);
- return -1;
- }
- if (!pCDSCtlr) return -1;
- if (!pCDSCtlr->FSLog->FLogCfg.Data) return -1;
- try
- {
- if (pCDSCtlr->FSLog->FLogCfg.Data) pCDSCtlr->FSLog->LogData(ASndRcv, AData, ALen);
- if (!pCDSCtlr->FDispLog) return -1;
- IPC_LOG_MESSAGE *pLog = g_logBuff.GetBuff();
- if (pLog)
- {
- memset(pLog->Msg, 0x00, sizeof(pLog->Msg));
- pLog->From = from_srvTcp;
- pLog->Target = log_com;
- pLog->Kind = eLOG_DATA;
- pLog->Flag = ASndRcv[0] == 'S' ? 1 : 2;
- pLog->Write = false;
- pLog->Tm = Now();
- pLog->Type = 'S';
- pLog->Obj = pCDSCtlr->FSLog;
- pLog->Ctlr = pCDSCtlr;
- pLog->Len = ALen > MAX_LOG_BUFFER ? MAX_LOG_BUFFER-1 : ALen;
- memcpy(pLog->Msg, (char*)AData, pLog->Len);
- g_logQ.PushTimeout((DWORD)pLog, 2000);
- }
- }
- catch(Exception &e)
- {
- }
- return 0;
- }
- //---------------------------------------------------------------------------
- int TClientSession::LogWrite(int ALogKind, char *AFmt, ...)
- {
- va_list ap;
- int cnt = 0;
- char szFmtData[MAX_LOG_BUFFER];
- // FrmCommLog 창에 뿌리는거
- TCDSCtlr* pCDSCtlr = FCDSLogCtlr;
- if (!pCDSCtlr) return -1;
- // if (!pCDSCtlr->FDispLog) return -1;
- bool bLog = false;
- switch(ALogKind)
- {
- case eLOG_INFO : bLog = pCDSCtlr->FSLog->FLogCfg.Info; break;
- case eLOG_DATA : bLog = pCDSCtlr->FSLog->FLogCfg.Data; break;
- case eLOG_ERROR : bLog = pCDSCtlr->FSLog->FLogCfg.Error; break;
- case eLOG_WARNING: bLog = pCDSCtlr->FSLog->FLogCfg.Warning; break;
- case eLOG_DEBUG : bLog = pCDSCtlr->FSLog->FLogCfg.Debug; break;
- case eLOG_DETAIL : bLog = pCDSCtlr->FSLog->FLogCfg.Detail; break;
- }
- if (!bLog) return -1;
- try
- {
- IPC_LOG_MESSAGE *pLog = g_logBuff.GetBuff();
- if (pLog)
- {
- va_start(ap, AFmt);
- cnt = vsprintf(szFmtData, AFmt, ap);
- va_end(ap);
- memset(pLog->Msg, 0x00, sizeof(pLog->Msg));
- pLog->From = from_srvTcp;
- pLog->Target = log_com;
- pLog->Kind = ALogKind;
- pLog->Flag = 0;
- pLog->Write = true;
- pLog->Tm = Now();
- pLog->Type = 'S';
- pLog->Obj = pCDSCtlr->FSLog;
- pLog->Ctlr = pCDSCtlr;
- sprintf(pLog->Msg, "+SVR %s, %s", pCDSCtlr->CTLR_NMBR.c_str(), szFmtData);
- pLog->Len = strlen(pLog->Msg);
- g_logQ.PushTimeout((DWORD)pLog, 2000);
- }
- }
- catch(Exception &e)
- {
- }
- return cnt;
- }
- //---------------------------------------------------------------------------
- int TClientSession::SysLogWrite(int ALogKind, char *AFmt, ...)
- {
- va_list ap;
- int cnt = 0;
- char szFmtData[MAX_LOG_BUFFER];
- // FrmSysLog 창에 뿌리는거
- TCDSCtlr* pCDSCtlr = FCDSLogCtlr;
- if (!pCDSCtlr) return -1;
- if (!pCDSCtlr->FSLog) return -1;
- bool bLog = false;
- switch(ALogKind)
- {
- case eLOG_INFO : bLog = pCDSCtlr->FSLog->FLogCfg.Info; break;
- case eLOG_DATA : bLog = pCDSCtlr->FSLog->FLogCfg.Data; break;
- case eLOG_ERROR : bLog = pCDSCtlr->FSLog->FLogCfg.Error; break;
- case eLOG_WARNING: bLog = pCDSCtlr->FSLog->FLogCfg.Warning; break;
- case eLOG_DEBUG : bLog = pCDSCtlr->FSLog->FLogCfg.Debug; break;
- case eLOG_DETAIL : bLog = pCDSCtlr->FSLog->FLogCfg.Detail; break;
- }
- if (!bLog) return -1;
- try
- {
- IPC_LOG_MESSAGE *pLog = g_logBuff.GetBuff();
- if (pLog)
- {
- va_start(ap, AFmt);
- cnt = vsprintf(szFmtData, AFmt, ap);
- va_end(ap);
- memset(pLog->Msg, 0x00, sizeof(pLog->Msg));
- pLog->From = from_srvTcp;
- pLog->Target = log_sys;
- pLog->Kind = ALogKind;
- pLog->Flag = 0;
- pLog->Write = true;
- pLog->Tm = Now();
- pLog->Type = 'S';
- pLog->Obj = pCDSCtlr->FSLog;
- pLog->Ctlr = pCDSCtlr;
- sprintf(pLog->Msg, "+SVR %s, %s", pCDSCtlr->CTLR_NMBR.c_str(), szFmtData);
- pLog->Len = strlen(szFmtData);
- g_logQ.PushTimeout((DWORD)pLog, 2000);
- }
- }
- catch(Exception &e)
- {
- }
- return cnt;
- }
- //---------------------------------------------------------------------------
|