123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- //---------------------------------------------------------------------------
- #include <vcl.h>
- #include <winsock2.h>
- #include "VMSCommLibF.h"
- #pragma hdrstop
- #include "FrmNetworkF.h"
- #include "PacketHandllingF.h"
- #include "ClientSessionF.h"
- #include "ClientSessionManagerF.h"
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- #pragma resource "*.dfm"
- TFrmNetwork *FrmNetwork;
- //---------------------------------------------------------------------------
- __fastcall TFrmNetwork::TFrmNetwork(TComponent* Owner)
- : TForm(Owner)
- {
- FInitialize = false;
- FStart = false;
- FLastErr = 0;
- FListenSock = INVALID_SOCKET;
- reMsg->Lines->Clear();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFrmNetwork::FormClose(TObject *Sender, TCloseAction &Action)
- {
- Hide();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFrmNetwork::FormDestroy(TObject *Sender)
- {
- Stop();
- }
- //---------------------------------------------------------------------------
- bool __fastcall TFrmNetwork::InitSock()
- {
- /// À©¼Ó ÃʱâÈ
- WSADATA wsa ;
- if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
- reMsg->Lines->Add("Network library initialize failed");
- FInitialize = true;
- return true;
- }
- //---------------------------------------------------------------------------
- void __fastcall TFrmNetwork::TermSock()
- {
- // À©¼Ó Á¾·á
- if (FInitialize)
- {
- WSACleanup();
- }
- FInitialize = false;
- }
- //---------------------------------------------------------------------------
- int TFrmNetwork::LogWrite(int ALogKind, char *AFmt, ...)
- {
- va_list ap;
- int cnt = 0;
- char szFmtData[MAX_LOG_BUFFER];
- bool bLog = false;
- switch(ALogKind)
- {
- case eLOG_INFO : bLog = g_LogCfg.Info; break;
- case eLOG_DATA : bLog = g_LogCfg.Data; break;
- case eLOG_ERROR : bLog = g_LogCfg.Error; break;
- case eLOG_WARNING: bLog = g_LogCfg.Warning; break;
- case eLOG_DEBUG : bLog = g_LogCfg.Debug; break;
- case eLOG_DETAIL : bLog = g_LogCfg.Detail; break;
- }
- if (!bLog) return -1;
- try
- {
- va_start(ap, AFmt);
- cnt = vsprintf(szFmtData, AFmt, ap);
- va_end(ap);
- IPC_LOG_MESSAGE *pLog = g_logBuff.GetBuff();
- if (pLog)
- {
- 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 = ITSLog;
- pLog->Ctlr = NULL;
- sprintf(pLog->Msg, "+SVR %s", szFmtData);
- pLog->Len = strlen(pLog->Msg);
- LogWrite((void*)pLog);
- g_logQ.PushTimeout((DWORD)pLog, 2000);
- }
- }
- catch(Exception &e)
- {
- }
- return cnt;
- }
- //---------------------------------------------------------------------------
- #if 1
- void TFrmNetwork::LogWrite(void *pLog)
- {
- IPC_LOG_MESSAGE *ALog = (IPC_LOG_MESSAGE*)pLog;
- if (!ALog) return;
- try
- {
- AnsiString sLogKind = " [XXX] ";
- #if 0
- bool bLog = false;
- switch(ALog->Kind)
- {
- case eLOG_INFO : bLog = g_LogCfg.Info; sLogKind = " [INF] "; break;
- case eLOG_DATA : bLog = g_LogCfg.Data; sLogKind = " [DAT] "; break;
- case eLOG_ERROR : bLog = g_LogCfg.Error; sLogKind = " [ERR] "; break;
- case eLOG_WARNING: bLog = g_LogCfg.Warning; sLogKind = " [WAN] "; break;
- case eLOG_DEBUG : bLog = g_LogCfg.Debug; sLogKind = " [DBG] "; break;
- case eLOG_DETAIL : bLog = g_LogCfg.Detail; sLogKind = " [DET] "; break;
- }
- if (!bLog) return -1;
- #else
- switch(ALog->Kind)
- {
- case eLOG_INFO : sLogKind = " [INF] "; break;
- case eLOG_DATA : sLogKind = " [DAT] "; break;
- case eLOG_ERROR : sLogKind = " [ERR] "; break;
- case eLOG_WARNING: sLogKind = " [WAN] "; break;
- case eLOG_DEBUG : sLogKind = " [DBG] "; break;
- case eLOG_DETAIL : sLogKind = " [DET] "; break;
- }
- #endif
- try
- {
- if (reMsg->Lines->Count >= g_AppCfg.nMaxLogLines)
- reMsg->Lines->Clear();
- reMsg->Lines->Add(ALog->Tm.FormatString("hh:nn:ss") + "." + Now().FormatString("ss") + sLogKind + String(ALog->Msg));
- }
- catch(Exception &e)
- {
- }
- }
- __finally
- {
- }
- }
- #endif
- //---------------------------------------------------------------------------
- bool __fastcall TFrmNetwork::Start()
- {
- SOCKET listenSock = INVALID_SOCKET;
- SOCKADDR_IN sockAddr;
- FLastErr = 0;
- if (!InitSock())
- {
- SocketError();
- LERROR("Socket library loading fail: %d.%s", FLastErr, FErrorString.c_str());
- return false;
- }
- listenSock = socket(AF_INET, SOCK_STREAM, 0);
- if (listenSock == INVALID_SOCKET)
- {
- SocketError();
- LERROR("Socket socket error: %d.%s", FLastErr, FErrorString.c_str());
- return false;
- }
- int opt = 1;
- setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(int));
- ZeroMemory(&sockAddr, sizeof(sockAddr));
- sockAddr.sin_family = AF_INET;
- sockAddr.sin_addr.s_addr = INADDR_ANY;
- sockAddr.sin_port = htons(g_AppCfg.comm.nListenPort);
- FLastErr = bind(listenSock, (SOCKADDR FAR *)&sockAddr, sizeof(sockAddr));
- if (FLastErr != 0)
- {
- SocketError();
- LERROR("Socket bind error: %d.%s", FLastErr, FErrorString.c_str());
- CloseSocket(listenSock);
- return false;
- }
- FLastErr = listen(listenSock, 50);
- if (FLastErr < 0)
- {
- SocketError();
- LERROR("Socket listen error: %d.%s", FLastErr, FErrorString.c_str());
- CloseSocket(listenSock);
- return false;
- }
- FLastErr = WSAAsyncSelect(listenSock, this->Handle, WM_SOCKET_ACCEPT, FD_ACCEPT);
- if (FLastErr != 0)
- {
- SocketError();
- LERROR("Socket WSAAsyncSelect error: %d.%s", FLastErr, FErrorString.c_str());
- CloseSocket(listenSock);
- return false;
- }
- FStart = true;
- FListenSock = listenSock;
- LINFO("TCP Server Start ok: %d", listenSock);
- return true;
- }
- //---------------------------------------------------------------------------
- void __fastcall TFrmNetwork::Stop()
- {
- if (FListenSock != INVALID_SOCKET)
- {
- CloseSocket(FListenSock);
- FStart = false;
- FLastErr = 0;
- FListenSock = INVALID_SOCKET;
- }
- TermSock();
- }
- //---------------------------------------------------------------------------
- void __fastcall TFrmNetwork::OnAcceptClient(TMessage &Msg)
- {
- SOCKET sLinstenSock = (SOCKET)Msg.WParam;
- WORD nErr = WSAGETSELECTERROR(Msg.LParam);
- WORD nEvent = WSAGETSELECTEVENT(Msg.LParam);
- TClientSession *pSession = NULL;
- if (nErr != NO_ERROR)
- {
- SocketError(nErr);
- LERROR("Accept Event error: %d.%s", FLastErr, FErrorString.c_str());
- return;
- }
- LINFO("TCP Client Connect Request");
- if (nEvent != FD_ACCEPT)
- {
- LERROR("OnAcceptClient Unknown Event: %d", nEvent);
- return ;
- }
- SOCKADDR_IN addrClient;
- int nAddrClient;
- SOCKET sClientSock = INVALID_SOCKET;
- nAddrClient = sizeof(addrClient);
- sClientSock = accept(sLinstenSock, (struct sockaddr *)&addrClient, (int FAR *)&nAddrClient);
- if (sClientSock == INVALID_SOCKET)
- {
- SocketError();
- LERROR("Accept accept error: %d.%s", FLastErr, FErrorString.c_str());
- return ;
- }
- pSession = ClientSessionManager->CreateClientSession(sClientSock, &addrClient);
- if (!pSession)
- {
- SocketError();
- LERROR("Accept session allocation failed: %s, %d.%s", pSession->IpAddress.c_str(), FLastErr, FErrorString.c_str());
- CloseSocket(sClientSock);
- return ;
- }
- IPC_JOB_MESSAGE *pMsg = g_jobBuff.GetBuff();
- pMsg->ObjPtr = (DWORD)pSession;
- //if (WSAAsyncSelect(pSession->Socket, this->Handle, WM_SOCKET_SELECT, FD_READ | FD_WRITE | FD_CLOSE) > 0)
- if (WSAAsyncSelect(pSession->Socket, this->Handle, WM_SOCKET_SELECT, FD_READ | FD_CLOSE) > 0)
- {
- SocketError();
- CloseSocket(sClientSock);
- LERROR("OnAcceptClient WSAAsyncSelect error: %d.%s", FLastErr, FErrorString.c_str());
- pSession->State = eSS_OnDisconnect;
- pMsg->Type = eTcpClose;
- g_jobQ.PushBlocking((DWORD)pMsg);
- return ;
- }
- LINFO("TCP Client Connect Accept: %s [%d]", pSession->IpAddress.c_str(), sClientSock);//pSession->Port);
- pMsg->Type = eTcpConnect;
- g_jobQ.PushBlocking((DWORD)pMsg);
- }
- //---------------------------------------------------------------------------
- void __fastcall TFrmNetwork::OnSelectClient(TMessage &Msg)
- {
- SOCKET sClientSock = (SOCKET)Msg.WParam;
- WORD nErr = WSAGETSELECTERROR(Msg.LParam);
- WORD nEvent = WSAGETSELECTEVENT(Msg.LParam);
- TClientSession *pSession = NULL;
- u_long nInBytes;
- int nFreeSize;
- int nRecvLen;
- AnsiString sIpAddress;
- SOCKADDR_IN addrClient;
- int addrlen = sizeof(addrClient);
- getpeername(sClientSock, (SOCKADDR*)&addrClient, &addrlen);
- sIpAddress.printf("%s[%d]", inet_ntoa(addrClient.sin_addr), sClientSock);
- pSession = ClientSessionManager->FindClientSession(sClientSock);
- if (!pSession)
- {
- LERROR("Select client not found from session manager: %s", sIpAddress.c_str());
- CloseSocket(sClientSock);
- return ;
- }
- IPC_JOB_MESSAGE *pMsg = g_jobBuff.GetBuff();
- if (nErr != NO_ERROR)
- {
- SocketError(nErr);
- LERROR("Socket Select Client Event Error: %d.%s", FLastErr, FErrorString.c_str());
- pMsg->Type = eTcpErrorEvent;
- pMsg->ObjPtr = (DWORD)pSession;
- pSession->State = eSS_OnDisconnect;
- g_jobQ.PushBlocking((DWORD)pMsg);
- //pSession->Disconnect();
- return;
- }
- switch(nEvent)
- {
- case FD_READ:
- {
- pMsg->Type = eTcpRecv;
- pMsg->ObjPtr = (DWORD)pSession;
- nFreeSize = pSession->GetFreeSpaceSize();
- nFreeSize = (nFreeSize < MAX_TCP_BUFF) ? nFreeSize : MAX_TCP_BUFF;
- nRecvLen = recv(pSession->Socket, pMsg->Buff, nFreeSize, 0);
- if (nRecvLen == SOCKET_ERROR)
- {
- if (WSAGetLastError() != WSAEWOULDBLOCK)
- {
- SocketError();
- LERROR("Select client recv error: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
- pSession->State = eSS_OnDisconnect;
- pMsg->Type = eTcpErrorRecv;
- }
- }
- if (nRecvLen == 0)
- {
- PostMessage(this->Handle, WM_SOCKET_SELECT, sClientSock, FD_READ);
- LERROR("Select client recv length zero: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
- return;
- }
- else
- {
- pMsg->Len = nRecvLen;
- LDEBUG("Select client recv: %s, %6d bytes recv", sIpAddress.c_str(), pMsg->Len);
- }
- #if 0
- int nRcvSize = pSession->GetFreeBuffSize();
- char *pRcvBuff = pSession->GetBuff();
- nErr = ioctlsocket(pSession->Socket, FIONREAD, &nInBytes);
- if (nErr == SOCKET_ERROR)
- {
- SocketError();
- LERROR("Select client ioctlsocket error: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
- pSession->State = eSS_OnDisconnect;
- pMsg->Type = eTcpErrorRecv;
- }
- else
- {
- nRcvSize = nRcvSize > (int)nInBytes ? nInBytes : nRcvSize;
- int nRecvLen = recv(pSession->Socket, pRcvBuff, nRcvSize, 0);
- if (nRecvLen != nRcvSize)
- {
- SocketError();
- LERROR("Select client recv error: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
- pSession->State = eSS_OnDisconnect;
- }
- else
- {
- LDEBUG("Select client recv: %s, %6d bytes recv, %d InBytes", sIpAddress.c_str(), nRecvLen, (int)nInBytes);
- }
- }
- #endif
- }
- break;
- case FD_WRITE:
- break;
- case FD_CLOSE:
- pMsg->Type = eTcpClose;
- pMsg->ObjPtr = (DWORD)pSession;
- pSession->State = eSS_OnDisconnect;
- LERROR("Socket Select client OnClose: %s", sIpAddress.c_str());
- break;
- }
- g_jobQ.PushBlocking((DWORD)pMsg);
- }
- //---------------------------------------------------------------------------
- int __fastcall TFrmNetwork::CloseSocket(SOCKET& ASock)
- {
- LINGER linger;
- int res = 0;
- if (ASock == INVALID_SOCKET)
- {
- return 0;
- }
- linger.l_onoff = 1;
- linger.l_linger = 0;
- setsockopt(ASock,
- SOL_SOCKET,
- SO_LINGER,
- (CHAR FAR *)&linger,
- sizeof(linger));
- res = closesocket(ASock);
- ASock = INVALID_SOCKET;
- return res;
- }
- //---------------------------------------------------------------------------
- int __fastcall TFrmNetwork::SocketError(int AError/*=-1*/)
- {
- if (AError == -1) FLastErr = WSAGetLastError();
- else FLastErr = AError;
- 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;
- }
- //---------------------------------------------------------------------------
|