//--------------------------------------------------------------------------- #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; } //---------------------------------------------------------------------------