FrmNetworkF.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #include <winsock2.h>
  4. #include "VMSCommLibF.h"
  5. #pragma hdrstop
  6. #include "FrmNetworkF.h"
  7. #include "PacketHandllingF.h"
  8. #include "ClientSessionF.h"
  9. #include "ClientSessionManagerF.h"
  10. //---------------------------------------------------------------------------
  11. #pragma package(smart_init)
  12. #pragma resource "*.dfm"
  13. TFrmNetwork *FrmNetwork;
  14. //---------------------------------------------------------------------------
  15. __fastcall TFrmNetwork::TFrmNetwork(TComponent* Owner)
  16. : TForm(Owner)
  17. {
  18. FInitialize = false;
  19. FStart = false;
  20. FLastErr = 0;
  21. FListenSock = INVALID_SOCKET;
  22. reMsg->Lines->Clear();
  23. }
  24. //---------------------------------------------------------------------------
  25. void __fastcall TFrmNetwork::FormClose(TObject *Sender, TCloseAction &Action)
  26. {
  27. Hide();
  28. }
  29. //---------------------------------------------------------------------------
  30. void __fastcall TFrmNetwork::FormDestroy(TObject *Sender)
  31. {
  32. Stop();
  33. }
  34. //---------------------------------------------------------------------------
  35. bool __fastcall TFrmNetwork::InitSock()
  36. {
  37. /// À©¼Ó ÃʱâÈ­
  38. WSADATA wsa ;
  39. if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
  40. reMsg->Lines->Add("Network library initialize failed");
  41. FInitialize = true;
  42. return true;
  43. }
  44. //---------------------------------------------------------------------------
  45. void __fastcall TFrmNetwork::TermSock()
  46. {
  47. // À©¼Ó Á¾·á
  48. if (FInitialize)
  49. {
  50. WSACleanup();
  51. }
  52. FInitialize = false;
  53. }
  54. //---------------------------------------------------------------------------
  55. int TFrmNetwork::LogWrite(int ALogKind, char *AFmt, ...)
  56. {
  57. va_list ap;
  58. int cnt = 0;
  59. char szFmtData[MAX_LOG_BUFFER];
  60. bool bLog = false;
  61. switch(ALogKind)
  62. {
  63. case eLOG_INFO : bLog = g_LogCfg.Info; break;
  64. case eLOG_DATA : bLog = g_LogCfg.Data; break;
  65. case eLOG_ERROR : bLog = g_LogCfg.Error; break;
  66. case eLOG_WARNING: bLog = g_LogCfg.Warning; break;
  67. case eLOG_DEBUG : bLog = g_LogCfg.Debug; break;
  68. case eLOG_DETAIL : bLog = g_LogCfg.Detail; break;
  69. }
  70. if (!bLog) return -1;
  71. try
  72. {
  73. va_start(ap, AFmt);
  74. cnt = vsprintf(szFmtData, AFmt, ap);
  75. va_end(ap);
  76. IPC_LOG_MESSAGE *pLog = g_logBuff.GetBuff();
  77. if (pLog)
  78. {
  79. memset(pLog->Msg, 0x00, sizeof(pLog->Msg));
  80. pLog->From = from_srvTcp;
  81. pLog->Target = log_sys;
  82. pLog->Kind = ALogKind;
  83. pLog->Flag = 0;
  84. pLog->Write = true;
  85. pLog->Tm = Now();
  86. pLog->Type = 'S';
  87. pLog->Obj = ITSLog;
  88. pLog->Ctlr = NULL;
  89. sprintf(pLog->Msg, "+SVR %s", szFmtData);
  90. pLog->Len = strlen(pLog->Msg);
  91. LogWrite((void*)pLog);
  92. g_logQ.PushTimeout((DWORD)pLog, 2000);
  93. }
  94. }
  95. catch(Exception &e)
  96. {
  97. }
  98. return cnt;
  99. }
  100. //---------------------------------------------------------------------------
  101. #if 1
  102. void TFrmNetwork::LogWrite(void *pLog)
  103. {
  104. IPC_LOG_MESSAGE *ALog = (IPC_LOG_MESSAGE*)pLog;
  105. if (!ALog) return;
  106. try
  107. {
  108. AnsiString sLogKind = " [XXX] ";
  109. #if 0
  110. bool bLog = false;
  111. switch(ALog->Kind)
  112. {
  113. case eLOG_INFO : bLog = g_LogCfg.Info; sLogKind = " [INF] "; break;
  114. case eLOG_DATA : bLog = g_LogCfg.Data; sLogKind = " [DAT] "; break;
  115. case eLOG_ERROR : bLog = g_LogCfg.Error; sLogKind = " [ERR] "; break;
  116. case eLOG_WARNING: bLog = g_LogCfg.Warning; sLogKind = " [WAN] "; break;
  117. case eLOG_DEBUG : bLog = g_LogCfg.Debug; sLogKind = " [DBG] "; break;
  118. case eLOG_DETAIL : bLog = g_LogCfg.Detail; sLogKind = " [DET] "; break;
  119. }
  120. if (!bLog) return -1;
  121. #else
  122. switch(ALog->Kind)
  123. {
  124. case eLOG_INFO : sLogKind = " [INF] "; break;
  125. case eLOG_DATA : sLogKind = " [DAT] "; break;
  126. case eLOG_ERROR : sLogKind = " [ERR] "; break;
  127. case eLOG_WARNING: sLogKind = " [WAN] "; break;
  128. case eLOG_DEBUG : sLogKind = " [DBG] "; break;
  129. case eLOG_DETAIL : sLogKind = " [DET] "; break;
  130. }
  131. #endif
  132. try
  133. {
  134. if (reMsg->Lines->Count >= g_AppCfg.nMaxLogLines)
  135. reMsg->Lines->Clear();
  136. reMsg->Lines->Add(ALog->Tm.FormatString("hh:nn:ss") + "." + Now().FormatString("ss") + sLogKind + String(ALog->Msg));
  137. }
  138. catch(Exception &e)
  139. {
  140. }
  141. }
  142. __finally
  143. {
  144. }
  145. }
  146. #endif
  147. //---------------------------------------------------------------------------
  148. bool __fastcall TFrmNetwork::Start()
  149. {
  150. SOCKET listenSock = INVALID_SOCKET;
  151. SOCKADDR_IN sockAddr;
  152. FLastErr = 0;
  153. if (!InitSock())
  154. {
  155. SocketError();
  156. LERROR("Socket library loading fail: %d.%s", FLastErr, FErrorString.c_str());
  157. return false;
  158. }
  159. listenSock = socket(AF_INET, SOCK_STREAM, 0);
  160. if (listenSock == INVALID_SOCKET)
  161. {
  162. SocketError();
  163. LERROR("Socket socket error: %d.%s", FLastErr, FErrorString.c_str());
  164. return false;
  165. }
  166. int opt = 1;
  167. setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(int));
  168. ZeroMemory(&sockAddr, sizeof(sockAddr));
  169. sockAddr.sin_family = AF_INET;
  170. sockAddr.sin_addr.s_addr = INADDR_ANY;
  171. sockAddr.sin_port = htons(g_AppCfg.comm.nListenPort);
  172. FLastErr = bind(listenSock, (SOCKADDR FAR *)&sockAddr, sizeof(sockAddr));
  173. if (FLastErr != 0)
  174. {
  175. SocketError();
  176. LERROR("Socket bind error: %d.%s", FLastErr, FErrorString.c_str());
  177. CloseSocket(listenSock);
  178. return false;
  179. }
  180. FLastErr = listen(listenSock, 50);
  181. if (FLastErr < 0)
  182. {
  183. SocketError();
  184. LERROR("Socket listen error: %d.%s", FLastErr, FErrorString.c_str());
  185. CloseSocket(listenSock);
  186. return false;
  187. }
  188. FLastErr = WSAAsyncSelect(listenSock, this->Handle, WM_SOCKET_ACCEPT, FD_ACCEPT);
  189. if (FLastErr != 0)
  190. {
  191. SocketError();
  192. LERROR("Socket WSAAsyncSelect error: %d.%s", FLastErr, FErrorString.c_str());
  193. CloseSocket(listenSock);
  194. return false;
  195. }
  196. FStart = true;
  197. FListenSock = listenSock;
  198. LINFO("TCP Server Start ok: %d", listenSock);
  199. return true;
  200. }
  201. //---------------------------------------------------------------------------
  202. void __fastcall TFrmNetwork::Stop()
  203. {
  204. if (FListenSock != INVALID_SOCKET)
  205. {
  206. CloseSocket(FListenSock);
  207. FStart = false;
  208. FLastErr = 0;
  209. FListenSock = INVALID_SOCKET;
  210. }
  211. TermSock();
  212. }
  213. //---------------------------------------------------------------------------
  214. void __fastcall TFrmNetwork::OnAcceptClient(TMessage &Msg)
  215. {
  216. SOCKET sLinstenSock = (SOCKET)Msg.WParam;
  217. WORD nErr = WSAGETSELECTERROR(Msg.LParam);
  218. WORD nEvent = WSAGETSELECTEVENT(Msg.LParam);
  219. TClientSession *pSession = NULL;
  220. if (nErr != NO_ERROR)
  221. {
  222. SocketError(nErr);
  223. LERROR("Accept Event error: %d.%s", FLastErr, FErrorString.c_str());
  224. return;
  225. }
  226. LINFO("TCP Client Connect Request");
  227. if (nEvent != FD_ACCEPT)
  228. {
  229. LERROR("OnAcceptClient Unknown Event: %d", nEvent);
  230. return ;
  231. }
  232. SOCKADDR_IN addrClient;
  233. int nAddrClient;
  234. SOCKET sClientSock = INVALID_SOCKET;
  235. nAddrClient = sizeof(addrClient);
  236. sClientSock = accept(sLinstenSock, (struct sockaddr *)&addrClient, (int FAR *)&nAddrClient);
  237. if (sClientSock == INVALID_SOCKET)
  238. {
  239. SocketError();
  240. LERROR("Accept accept error: %d.%s", FLastErr, FErrorString.c_str());
  241. return ;
  242. }
  243. pSession = ClientSessionManager->CreateClientSession(sClientSock, &addrClient);
  244. if (!pSession)
  245. {
  246. SocketError();
  247. LERROR("Accept session allocation failed: %s, %d.%s", pSession->IpAddress.c_str(), FLastErr, FErrorString.c_str());
  248. CloseSocket(sClientSock);
  249. return ;
  250. }
  251. IPC_JOB_MESSAGE *pMsg = g_jobBuff.GetBuff();
  252. pMsg->ObjPtr = (DWORD)pSession;
  253. //if (WSAAsyncSelect(pSession->Socket, this->Handle, WM_SOCKET_SELECT, FD_READ | FD_WRITE | FD_CLOSE) > 0)
  254. if (WSAAsyncSelect(pSession->Socket, this->Handle, WM_SOCKET_SELECT, FD_READ | FD_CLOSE) > 0)
  255. {
  256. SocketError();
  257. CloseSocket(sClientSock);
  258. LERROR("OnAcceptClient WSAAsyncSelect error: %d.%s", FLastErr, FErrorString.c_str());
  259. pSession->State = eSS_OnDisconnect;
  260. pMsg->Type = eTcpClose;
  261. g_jobQ.PushBlocking((DWORD)pMsg);
  262. return ;
  263. }
  264. LINFO("TCP Client Connect Accept: %s [%d]", pSession->IpAddress.c_str(), sClientSock);//pSession->Port);
  265. pMsg->Type = eTcpConnect;
  266. g_jobQ.PushBlocking((DWORD)pMsg);
  267. }
  268. //---------------------------------------------------------------------------
  269. void __fastcall TFrmNetwork::OnSelectClient(TMessage &Msg)
  270. {
  271. SOCKET sClientSock = (SOCKET)Msg.WParam;
  272. WORD nErr = WSAGETSELECTERROR(Msg.LParam);
  273. WORD nEvent = WSAGETSELECTEVENT(Msg.LParam);
  274. TClientSession *pSession = NULL;
  275. u_long nInBytes;
  276. int nFreeSize;
  277. int nRecvLen;
  278. AnsiString sIpAddress;
  279. SOCKADDR_IN addrClient;
  280. int addrlen = sizeof(addrClient);
  281. getpeername(sClientSock, (SOCKADDR*)&addrClient, &addrlen);
  282. sIpAddress.printf("%s[%d]", inet_ntoa(addrClient.sin_addr), sClientSock);
  283. pSession = ClientSessionManager->FindClientSession(sClientSock);
  284. if (!pSession)
  285. {
  286. LERROR("Select client not found from session manager: %s", sIpAddress.c_str());
  287. CloseSocket(sClientSock);
  288. return ;
  289. }
  290. IPC_JOB_MESSAGE *pMsg = g_jobBuff.GetBuff();
  291. if (nErr != NO_ERROR)
  292. {
  293. SocketError(nErr);
  294. LERROR("Socket Select Client Event Error: %d.%s", FLastErr, FErrorString.c_str());
  295. pMsg->Type = eTcpErrorEvent;
  296. pMsg->ObjPtr = (DWORD)pSession;
  297. pSession->State = eSS_OnDisconnect;
  298. g_jobQ.PushBlocking((DWORD)pMsg);
  299. //pSession->Disconnect();
  300. return;
  301. }
  302. switch(nEvent)
  303. {
  304. case FD_READ:
  305. {
  306. pMsg->Type = eTcpRecv;
  307. pMsg->ObjPtr = (DWORD)pSession;
  308. nFreeSize = pSession->GetFreeSpaceSize();
  309. nFreeSize = (nFreeSize < MAX_TCP_BUFF) ? nFreeSize : MAX_TCP_BUFF;
  310. nRecvLen = recv(pSession->Socket, pMsg->Buff, nFreeSize, 0);
  311. if (nRecvLen == SOCKET_ERROR)
  312. {
  313. if (WSAGetLastError() != WSAEWOULDBLOCK)
  314. {
  315. SocketError();
  316. LERROR("Select client recv error: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
  317. pSession->State = eSS_OnDisconnect;
  318. pMsg->Type = eTcpErrorRecv;
  319. }
  320. }
  321. if (nRecvLen == 0)
  322. {
  323. PostMessage(this->Handle, WM_SOCKET_SELECT, sClientSock, FD_READ);
  324. LERROR("Select client recv length zero: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
  325. return;
  326. }
  327. else
  328. {
  329. pMsg->Len = nRecvLen;
  330. LDEBUG("Select client recv: %s, %6d bytes recv", sIpAddress.c_str(), pMsg->Len);
  331. }
  332. #if 0
  333. int nRcvSize = pSession->GetFreeBuffSize();
  334. char *pRcvBuff = pSession->GetBuff();
  335. nErr = ioctlsocket(pSession->Socket, FIONREAD, &nInBytes);
  336. if (nErr == SOCKET_ERROR)
  337. {
  338. SocketError();
  339. LERROR("Select client ioctlsocket error: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
  340. pSession->State = eSS_OnDisconnect;
  341. pMsg->Type = eTcpErrorRecv;
  342. }
  343. else
  344. {
  345. nRcvSize = nRcvSize > (int)nInBytes ? nInBytes : nRcvSize;
  346. int nRecvLen = recv(pSession->Socket, pRcvBuff, nRcvSize, 0);
  347. if (nRecvLen != nRcvSize)
  348. {
  349. SocketError();
  350. LERROR("Select client recv error: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
  351. pSession->State = eSS_OnDisconnect;
  352. }
  353. else
  354. {
  355. LDEBUG("Select client recv: %s, %6d bytes recv, %d InBytes", sIpAddress.c_str(), nRecvLen, (int)nInBytes);
  356. }
  357. }
  358. #endif
  359. }
  360. break;
  361. case FD_WRITE:
  362. break;
  363. case FD_CLOSE:
  364. pMsg->Type = eTcpClose;
  365. pMsg->ObjPtr = (DWORD)pSession;
  366. pSession->State = eSS_OnDisconnect;
  367. LERROR("Socket Select client OnClose: %s", sIpAddress.c_str());
  368. break;
  369. }
  370. g_jobQ.PushBlocking((DWORD)pMsg);
  371. }
  372. //---------------------------------------------------------------------------
  373. int __fastcall TFrmNetwork::CloseSocket(SOCKET& ASock)
  374. {
  375. LINGER linger;
  376. int res = 0;
  377. if (ASock == INVALID_SOCKET)
  378. {
  379. return 0;
  380. }
  381. linger.l_onoff = 1;
  382. linger.l_linger = 0;
  383. setsockopt(ASock,
  384. SOL_SOCKET,
  385. SO_LINGER,
  386. (CHAR FAR *)&linger,
  387. sizeof(linger));
  388. res = closesocket(ASock);
  389. ASock = INVALID_SOCKET;
  390. return res;
  391. }
  392. //---------------------------------------------------------------------------
  393. int __fastcall TFrmNetwork::SocketError(int AError/*=-1*/)
  394. {
  395. if (AError == -1) FLastErr = WSAGetLastError();
  396. else FLastErr = AError;
  397. LPVOID lpMsgBuf = NULL;
  398. try
  399. {
  400. try
  401. {
  402. FormatMessage(
  403. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  404. NULL,
  405. FLastErr,
  406. //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  407. MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
  408. (LPTSTR) &lpMsgBuf,
  409. 0,
  410. NULL
  411. );
  412. char *pData = (char*)lpMsgBuf;
  413. if (strlen(pData) > 2)
  414. {
  415. pData[strlen(pData)-2] = 0x00;
  416. pData[strlen(pData)-1] = 0x00;
  417. }
  418. FErrorString.printf("%s", pData);
  419. }
  420. catch(Exception &e)
  421. {
  422. FErrorString.printf("%s, %s", AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  423. }
  424. }
  425. __finally
  426. {
  427. if (lpMsgBuf) LocalFree(lpMsgBuf);
  428. lpMsgBuf = NULL;
  429. }
  430. return FLastErr;
  431. }
  432. //---------------------------------------------------------------------------