FrmNetworkF.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  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. if (chkLogPause->Checked) {
  107. return;
  108. }
  109. try
  110. {
  111. AnsiString sLogKind = " [XXX] ";
  112. #if 0
  113. bool bLog = false;
  114. switch(ALog->Kind)
  115. {
  116. case eLOG_INFO : bLog = g_LogCfg.Info; sLogKind = " [INF] "; break;
  117. case eLOG_DATA : bLog = g_LogCfg.Data; sLogKind = " [DAT] "; break;
  118. case eLOG_ERROR : bLog = g_LogCfg.Error; sLogKind = " [ERR] "; break;
  119. case eLOG_WARNING: bLog = g_LogCfg.Warning; sLogKind = " [WAN] "; break;
  120. case eLOG_DEBUG : bLog = g_LogCfg.Debug; sLogKind = " [DBG] "; break;
  121. case eLOG_DETAIL : bLog = g_LogCfg.Detail; sLogKind = " [DET] "; break;
  122. }
  123. if (!bLog) return -1;
  124. #else
  125. switch(ALog->Kind)
  126. {
  127. case eLOG_INFO : sLogKind = " [INF] "; break;
  128. case eLOG_DATA : sLogKind = " [DAT] "; break;
  129. case eLOG_ERROR : sLogKind = " [ERR] "; break;
  130. case eLOG_WARNING: sLogKind = " [WAN] "; break;
  131. case eLOG_DEBUG : sLogKind = " [DBG] "; break;
  132. case eLOG_DETAIL : sLogKind = " [DET] "; break;
  133. }
  134. #endif
  135. try
  136. {
  137. if (reMsg->Lines->Count >= g_AppCfg.nMaxLogLines)
  138. reMsg->Lines->Clear();
  139. reMsg->Lines->Add(ALog->Tm.FormatString("hh:nn:ss") + "." + Now().FormatString("ss") + sLogKind + String(ALog->Msg));
  140. }
  141. catch(Exception &e)
  142. {
  143. }
  144. }
  145. __finally
  146. {
  147. }
  148. }
  149. #endif
  150. //---------------------------------------------------------------------------
  151. bool __fastcall TFrmNetwork::Start()
  152. {
  153. SOCKET listenSock = INVALID_SOCKET;
  154. SOCKADDR_IN sockAddr;
  155. FLastErr = 0;
  156. if (!InitSock())
  157. {
  158. SocketError();
  159. LERROR("Socket library loading fail: %d.%s", FLastErr, FErrorString.c_str());
  160. return false;
  161. }
  162. listenSock = socket(AF_INET, SOCK_STREAM, 0);
  163. if (listenSock == INVALID_SOCKET)
  164. {
  165. SocketError();
  166. LERROR("Socket socket error: %d.%s", FLastErr, FErrorString.c_str());
  167. return false;
  168. }
  169. int opt = 1;
  170. setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(int));
  171. ZeroMemory(&sockAddr, sizeof(sockAddr));
  172. sockAddr.sin_family = AF_INET;
  173. sockAddr.sin_addr.s_addr = INADDR_ANY;
  174. sockAddr.sin_port = htons(g_AppCfg.comm.nListenPort);
  175. FLastErr = bind(listenSock, (SOCKADDR FAR *)&sockAddr, sizeof(sockAddr));
  176. if (FLastErr != 0)
  177. {
  178. SocketError();
  179. LERROR("Socket bind error: %d.%s", FLastErr, FErrorString.c_str());
  180. CloseSocket(listenSock);
  181. return false;
  182. }
  183. FLastErr = listen(listenSock, 50);
  184. if (FLastErr < 0)
  185. {
  186. SocketError();
  187. LERROR("Socket listen error: %d.%s", FLastErr, FErrorString.c_str());
  188. CloseSocket(listenSock);
  189. return false;
  190. }
  191. FLastErr = WSAAsyncSelect(listenSock, this->Handle, WM_SOCKET_ACCEPT, FD_ACCEPT);
  192. if (FLastErr != 0)
  193. {
  194. SocketError();
  195. LERROR("Socket WSAAsyncSelect error: %d.%s", FLastErr, FErrorString.c_str());
  196. CloseSocket(listenSock);
  197. return false;
  198. }
  199. FStart = true;
  200. FListenSock = listenSock;
  201. LINFO("TCP Server Start ok: %d", listenSock);
  202. return true;
  203. }
  204. //---------------------------------------------------------------------------
  205. void __fastcall TFrmNetwork::Stop()
  206. {
  207. if (FListenSock != INVALID_SOCKET)
  208. {
  209. CloseSocket(FListenSock);
  210. FStart = false;
  211. FLastErr = 0;
  212. FListenSock = INVALID_SOCKET;
  213. }
  214. TermSock();
  215. }
  216. //---------------------------------------------------------------------------
  217. void __fastcall TFrmNetwork::OnAcceptClient(TMessage &Msg)
  218. {
  219. SOCKET sLinstenSock = (SOCKET)Msg.WParam;
  220. WORD nErr = WSAGETSELECTERROR(Msg.LParam);
  221. WORD nEvent = WSAGETSELECTEVENT(Msg.LParam);
  222. TClientSession *pSession = NULL;
  223. if (nErr != NO_ERROR)
  224. {
  225. SocketError(nErr);
  226. LERROR("Accept Event error: %d.%s", FLastErr, FErrorString.c_str());
  227. return;
  228. }
  229. LINFO("TCP Client Connect Request");
  230. if (nEvent != FD_ACCEPT)
  231. {
  232. LERROR("OnAcceptClient Unknown Event: %d", nEvent);
  233. return ;
  234. }
  235. SOCKADDR_IN addrClient;
  236. int nAddrClient;
  237. SOCKET sClientSock = INVALID_SOCKET;
  238. nAddrClient = sizeof(addrClient);
  239. sClientSock = accept(sLinstenSock, (struct sockaddr *)&addrClient, (int FAR *)&nAddrClient);
  240. if (sClientSock == INVALID_SOCKET)
  241. {
  242. SocketError();
  243. LERROR("Accept accept error: %d.%s", FLastErr, FErrorString.c_str());
  244. return ;
  245. }
  246. pSession = ClientSessionManager->CreateClientSession(sClientSock, &addrClient);
  247. if (!pSession)
  248. {
  249. SocketError();
  250. LERROR("Accept session allocation failed: %s, %d.%s", pSession->IpAddress.c_str(), FLastErr, FErrorString.c_str());
  251. CloseSocket(sClientSock);
  252. return ;
  253. }
  254. IPC_JOB_MESSAGE *pMsg = g_jobBuff.GetBuff();
  255. pMsg->ObjPtr = (DWORD)pSession;
  256. //if (WSAAsyncSelect(pSession->Socket, this->Handle, WM_SOCKET_SELECT, FD_READ | FD_WRITE | FD_CLOSE) > 0)
  257. if (WSAAsyncSelect(pSession->Socket, this->Handle, WM_SOCKET_SELECT, FD_READ | FD_CLOSE) > 0)
  258. {
  259. SocketError();
  260. CloseSocket(sClientSock);
  261. LERROR("OnAcceptClient WSAAsyncSelect error: %d.%s", FLastErr, FErrorString.c_str());
  262. pSession->State = eSS_OnDisconnect;
  263. pMsg->Type = eTcpClose;
  264. g_jobQ.PushBlocking((DWORD)pMsg);
  265. return ;
  266. }
  267. LINFO("TCP Client Connect Accept: %s [%d]", pSession->IpAddress.c_str(), sClientSock);//pSession->Port);
  268. pMsg->Type = eTcpConnect;
  269. g_jobQ.PushBlocking((DWORD)pMsg);
  270. }
  271. //---------------------------------------------------------------------------
  272. void __fastcall TFrmNetwork::OnSelectClient(TMessage &Msg)
  273. {
  274. SOCKET sClientSock = (SOCKET)Msg.WParam;
  275. WORD nErr = WSAGETSELECTERROR(Msg.LParam);
  276. WORD nEvent = WSAGETSELECTEVENT(Msg.LParam);
  277. TClientSession *pSession = NULL;
  278. u_long nInBytes;
  279. int nFreeSize;
  280. int nRecvLen;
  281. AnsiString sIpAddress;
  282. SOCKADDR_IN addrClient;
  283. int addrlen = sizeof(addrClient);
  284. getpeername(sClientSock, (SOCKADDR*)&addrClient, &addrlen);
  285. sIpAddress.printf("%s[%d]", inet_ntoa(addrClient.sin_addr), sClientSock);
  286. pSession = ClientSessionManager->FindClientSession(sClientSock);
  287. if (!pSession)
  288. {
  289. LERROR("Select client not found from session manager: %s", sIpAddress.c_str());
  290. CloseSocket(sClientSock);
  291. return ;
  292. }
  293. IPC_JOB_MESSAGE *pMsg = g_jobBuff.GetBuff();
  294. if (nErr != NO_ERROR)
  295. {
  296. SocketError(nErr);
  297. LERROR("Socket Select Client Event Error: %d.%s", FLastErr, FErrorString.c_str());
  298. pMsg->Type = eTcpErrorEvent;
  299. pMsg->ObjPtr = (DWORD)pSession;
  300. pSession->State = eSS_OnDisconnect;
  301. g_jobQ.PushBlocking((DWORD)pMsg);
  302. //pSession->Disconnect();
  303. return;
  304. }
  305. switch(nEvent)
  306. {
  307. case FD_READ:
  308. {
  309. pMsg->Type = eTcpRecv;
  310. pMsg->ObjPtr = (DWORD)pSession;
  311. nFreeSize = pSession->GetFreeSpaceSize();
  312. nFreeSize = (nFreeSize < MAX_TCP_BUFF) ? nFreeSize : MAX_TCP_BUFF;
  313. nRecvLen = recv(pSession->Socket, pMsg->Buff, nFreeSize, 0);
  314. if (nRecvLen == SOCKET_ERROR)
  315. {
  316. if (WSAGetLastError() != WSAEWOULDBLOCK)
  317. {
  318. SocketError();
  319. LERROR("Select client recv error: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
  320. pSession->State = eSS_OnDisconnect;
  321. pMsg->Type = eTcpErrorRecv;
  322. }
  323. }
  324. if (nRecvLen == 0)
  325. {
  326. PostMessage(this->Handle, WM_SOCKET_SELECT, sClientSock, FD_READ);
  327. LERROR("Select client recv length zero: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
  328. return;
  329. }
  330. else
  331. {
  332. pMsg->Len = nRecvLen;
  333. LDEBUG("Select client recv: %s, %6d bytes recv", sIpAddress.c_str(), pMsg->Len);
  334. }
  335. #if 0
  336. int nRcvSize = pSession->GetFreeBuffSize();
  337. char *pRcvBuff = pSession->GetBuff();
  338. nErr = ioctlsocket(pSession->Socket, FIONREAD, &nInBytes);
  339. if (nErr == SOCKET_ERROR)
  340. {
  341. SocketError();
  342. LERROR("Select client ioctlsocket error: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
  343. pSession->State = eSS_OnDisconnect;
  344. pMsg->Type = eTcpErrorRecv;
  345. }
  346. else
  347. {
  348. nRcvSize = nRcvSize > (int)nInBytes ? nInBytes : nRcvSize;
  349. int nRecvLen = recv(pSession->Socket, pRcvBuff, nRcvSize, 0);
  350. if (nRecvLen != nRcvSize)
  351. {
  352. SocketError();
  353. LERROR("Select client recv error: %s, %d.%s", sIpAddress.c_str(), FLastErr, FErrorString.c_str());
  354. pSession->State = eSS_OnDisconnect;
  355. }
  356. else
  357. {
  358. LDEBUG("Select client recv: %s, %6d bytes recv, %d InBytes", sIpAddress.c_str(), nRecvLen, (int)nInBytes);
  359. }
  360. }
  361. #endif
  362. }
  363. break;
  364. case FD_WRITE:
  365. break;
  366. case FD_CLOSE:
  367. pMsg->Type = eTcpClose;
  368. pMsg->ObjPtr = (DWORD)pSession;
  369. pSession->State = eSS_OnDisconnect;
  370. LERROR("Socket Select client OnClose: %s", sIpAddress.c_str());
  371. break;
  372. }
  373. g_jobQ.PushBlocking((DWORD)pMsg);
  374. }
  375. //---------------------------------------------------------------------------
  376. int __fastcall TFrmNetwork::CloseSocket(SOCKET& ASock)
  377. {
  378. LINGER linger;
  379. int res = 0;
  380. if (ASock == INVALID_SOCKET)
  381. {
  382. return 0;
  383. }
  384. linger.l_onoff = 1;
  385. linger.l_linger = 0;
  386. setsockopt(ASock,
  387. SOL_SOCKET,
  388. SO_LINGER,
  389. (CHAR FAR *)&linger,
  390. sizeof(linger));
  391. res = closesocket(ASock);
  392. ASock = INVALID_SOCKET;
  393. return res;
  394. }
  395. //---------------------------------------------------------------------------
  396. int __fastcall TFrmNetwork::SocketError(int AError/*=-1*/)
  397. {
  398. if (AError == -1) FLastErr = WSAGetLastError();
  399. else FLastErr = AError;
  400. LPVOID lpMsgBuf = NULL;
  401. try
  402. {
  403. try
  404. {
  405. FormatMessage(
  406. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  407. NULL,
  408. FLastErr,
  409. //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  410. MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
  411. (LPTSTR) &lpMsgBuf,
  412. 0,
  413. NULL
  414. );
  415. char *pData = (char*)lpMsgBuf;
  416. if (strlen(pData) > 2)
  417. {
  418. pData[strlen(pData)-2] = 0x00;
  419. pData[strlen(pData)-1] = 0x00;
  420. }
  421. FErrorString.printf("%s", pData);
  422. }
  423. catch(Exception &e)
  424. {
  425. FErrorString.printf("%s, %s", AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  426. }
  427. }
  428. __finally
  429. {
  430. if (lpMsgBuf) LocalFree(lpMsgBuf);
  431. lpMsgBuf = NULL;
  432. }
  433. return FLastErr;
  434. }
  435. //---------------------------------------------------------------------------
  436. void __fastcall TFrmNetwork::btnCopyClick(TObject *Sender)
  437. {
  438. try
  439. {
  440. reMsg->SelectAll();
  441. reMsg->CopyToClipboard();
  442. Application->ProcessMessages();
  443. }
  444. catch(Exception &e)
  445. {
  446. }
  447. }
  448. //---------------------------------------------------------------------------
  449. void __fastcall TFrmNetwork::btnClearClick(TObject *Sender)
  450. {
  451. try
  452. {
  453. reMsg->Lines->Clear();
  454. Application->ProcessMessages();
  455. }
  456. catch(Exception &e)
  457. {
  458. }
  459. }
  460. //---------------------------------------------------------------------------