ServerDlg.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. // ServerDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Server.h"
  5. #include "ServerDlg.h"
  6. #include "afxdialogex.h"
  7. #include "../../../../Common/Src/WaitFor.h"
  8. #include "../../../../Common/Src/SysHelper.h"
  9. #ifdef _WIN64
  10. #ifdef _DEBUG
  11. #pragma comment(lib, "../../../Bin/HPSocket/x64/static/HPSocket-SSL_UD.lib")
  12. #else
  13. #pragma comment(lib, "../../../Bin/HPSocket/x64/static/HPSocket-SSL_U.lib")
  14. #endif
  15. #else
  16. #ifdef _DEBUG
  17. #pragma comment(lib, "../../../Bin/HPSocket/x86/static/HPSocket-SSL_UD.lib")
  18. #else
  19. #pragma comment(lib, "../../../Bin/HPSocket/x86/static/HPSocket-SSL_U.lib")
  20. #endif
  21. #endif
  22. // CServerDlg dialog
  23. #define DEFAULT_ADDRESS _T("0.0.0.0")
  24. #define DEFAULT_PORT _T("5555")
  25. CServerDlg::CServerDlg(CWnd* pParent /*=nullptr*/)
  26. : CDialogEx(CServerDlg::IDD, pParent), m_Server(this)
  27. , m_lClientCount(0L)
  28. , m_sslInitializer(SSL_SM_SERVER, g_s_iVerifyMode, g_s_lpszPemCertFile, g_s_lpszPemKeyFile, g_s_lpszKeyPasswod, g_s_lpszCAPemCertFileOrPath)
  29. {
  30. VERIFY(m_sslInitializer.IsValid());
  31. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  32. }
  33. void CServerDlg::DoDataExchange(CDataExchange* pDX)
  34. {
  35. CDialogEx::DoDataExchange(pDX);
  36. DDX_Control(pDX, IDC_INFO, m_Info);
  37. DDX_Control(pDX, IDC_START, m_Start);
  38. DDX_Control(pDX, IDC_STOP, m_Stop);
  39. DDX_Control(pDX, IDC_PORT, m_Port);
  40. DDX_Control(pDX, IDC_SEND_POLICY, m_SendPolicy);
  41. DDX_Control(pDX, IDC_THREAD_COUNT, m_ThreadCount);
  42. DDX_Control(pDX, IDC_MAX_CONN_COUNT, m_MaxConnCount);
  43. }
  44. BEGIN_MESSAGE_MAP(CServerDlg, CDialogEx)
  45. ON_WM_PAINT()
  46. ON_WM_QUERYDRAGICON()
  47. ON_BN_CLICKED(IDC_START, &CServerDlg::OnBnClickedStart)
  48. ON_BN_CLICKED(IDC_STOP, &CServerDlg::OnBnClickedStop)
  49. ON_MESSAGE(USER_INFO_MSG, OnUserInfoMsg)
  50. ON_WM_VKEYTOITEM()
  51. ON_WM_CLOSE()
  52. END_MESSAGE_MAP()
  53. // CServerDlg message handlers
  54. BOOL CServerDlg::OnInitDialog()
  55. {
  56. CDialogEx::OnInitDialog();
  57. // Set the icon for this dialog. The framework does this automatically
  58. // when the application's main window is not a dialog
  59. SetIcon(m_hIcon, TRUE); // Set big icon
  60. SetIcon(m_hIcon, FALSE); // Set small icon
  61. // TODO: Add extra initialization here
  62. CString strTitle;
  63. CString strOriginTitle;
  64. m_SendPolicy.SetCurSel(0);
  65. m_ThreadCount.SetCurSel(0);
  66. m_MaxConnCount.SetCurSel(0);
  67. m_Port.SetWindowText(DEFAULT_PORT);
  68. ::SetMainWnd(this);
  69. ::SetInfoList(&m_Info);
  70. SetAppState(ST_STOPPED);
  71. return TRUE; // return TRUE unless you set the focus to a control
  72. }
  73. void CServerDlg::OnClose()
  74. {
  75. /*
  76. if(m_Server->GetState() != SS_STOPED)
  77. {
  78. this->MessageBox(_T("stop IOCP Server first, pls !"), _T("forbiddden"));
  79. return;
  80. }
  81. */
  82. ::SetMainWnd(nullptr);
  83. __super::OnClose();
  84. }
  85. // If you add a minimize button to your dialog, you will need the code below
  86. // to draw the icon. For MFC applications using the document/view model,
  87. // this is automatically done for you by the framework.
  88. void CServerDlg::OnPaint()
  89. {
  90. if (IsIconic())
  91. {
  92. CPaintDC dc(this); // device context for painting
  93. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  94. // Center icon in client rectangle
  95. int cxIcon = GetSystemMetrics(SM_CXICON);
  96. int cyIcon = GetSystemMetrics(SM_CYICON);
  97. CRect rect;
  98. GetClientRect(&rect);
  99. int x = (rect.Width() - cxIcon + 1) / 2;
  100. int y = (rect.Height() - cyIcon + 1) / 2;
  101. // Draw the icon
  102. dc.DrawIcon(x, y, m_hIcon);
  103. }
  104. else
  105. {
  106. CDialogEx::OnPaint();
  107. }
  108. }
  109. // The system calls this function to obtain the cursor to display while the user drags
  110. // the minimized window.
  111. HCURSOR CServerDlg::OnQueryDragIcon()
  112. {
  113. return static_cast<HCURSOR>(m_hIcon);
  114. }
  115. BOOL CServerDlg::PreTranslateMessage(MSG* pMsg)
  116. {
  117. if (
  118. pMsg->message == WM_KEYDOWN
  119. &&( pMsg->wParam == VK_ESCAPE
  120. || pMsg->wParam == VK_CANCEL
  121. || pMsg->wParam == VK_RETURN
  122. ))
  123. return TRUE;
  124. return CDialog::PreTranslateMessage(pMsg);
  125. }
  126. void CServerDlg::SetAppState(EnAppState state)
  127. {
  128. if(m_enState == state)
  129. return;
  130. m_enState = state;
  131. if(this->GetSafeHwnd() == nullptr)
  132. return;
  133. m_Start.EnableWindow(m_enState == ST_STOPPED);
  134. m_Stop.EnableWindow(m_enState == ST_STARTED);
  135. m_Port.EnableWindow(m_enState == ST_STOPPED);
  136. m_SendPolicy.EnableWindow(m_enState == ST_STOPPED);
  137. m_ThreadCount.EnableWindow(m_enState == ST_STOPPED);
  138. m_MaxConnCount.EnableWindow(m_enState == ST_STOPPED);
  139. }
  140. void CServerDlg::OnBnClickedStart()
  141. {
  142. CString strPort;
  143. m_Port.GetWindowText(strPort);
  144. USHORT usPort = (USHORT)_ttoi(strPort);
  145. if(usPort == 0)
  146. {
  147. MessageBox(_T("Listen Port invalid, pls check!"), _T("Params Error"), MB_OK);
  148. m_Port.SetFocus();
  149. return;
  150. }
  151. EnSendPolicy enSendPolicy = (EnSendPolicy)m_SendPolicy.GetCurSel();
  152. CString strThreadCount;
  153. m_ThreadCount.GetWindowText(strThreadCount);
  154. int iThreadCount = _ttoi(strThreadCount);
  155. if(iThreadCount == 0)
  156. iThreadCount = min((::SysGetNumberOfProcessors() * 2 + 2), 500);
  157. else if(iThreadCount < 0 || iThreadCount > 500)
  158. {
  159. m_ThreadCount.SetFocus();
  160. return;
  161. }
  162. CString strMaxConnCount;
  163. m_MaxConnCount.GetWindowText(strMaxConnCount);
  164. int iMaxConnCount = _ttoi(strMaxConnCount);
  165. if(iMaxConnCount == 0)
  166. iMaxConnCount = 10;
  167. iMaxConnCount *= 1000;
  168. SetAppState(ST_STARTING);
  169. Reset();
  170. m_Server->SetSendPolicy(enSendPolicy);
  171. m_Server->SetWorkerThreadCount(iThreadCount);
  172. m_Server->SetMaxConnectionCount(iMaxConnCount);
  173. //m_Server->SetFreeSocketObjPool(500);
  174. //m_Server->SetFreeSocketObjHold(1500);
  175. //m_Server->SetFreeBufferObjPool(2000);
  176. //m_Server->SetFreeBufferObjHold(6000);
  177. //m_Server->SetSocketListenQueue(2000);
  178. //m_Server->SetAcceptSocketCount(2000);
  179. if(m_Server->Start(DEFAULT_ADDRESS, usPort))
  180. {
  181. ::LogServerStart(DEFAULT_ADDRESS, usPort);
  182. SetAppState(ST_STARTED);
  183. }
  184. else
  185. {
  186. ::LogServerStartFail(m_Server->GetLastError(), m_Server->GetLastErrorDesc());
  187. SetAppState(ST_STOPPED);
  188. }
  189. }
  190. void CServerDlg::OnBnClickedStop()
  191. {
  192. SetAppState(ST_STOPPING);
  193. if(m_Server->Stop())
  194. {
  195. ::LogServerStop();
  196. SetAppState(ST_STOPPED);
  197. }
  198. else
  199. {
  200. ASSERT(FALSE);
  201. }
  202. }
  203. int CServerDlg::OnVKeyToItem(UINT nKey, CListBox* pListBox, UINT nIndex)
  204. {
  205. if(nKey == 'C')
  206. pListBox->ResetContent();
  207. else if(nKey == 'R')
  208. {
  209. Reset();
  210. CString strMsg;
  211. strMsg.Format( _T(" *** Reset Statics: CC - %u, TS - %lld, TR - %lld"),
  212. m_lClientCount, m_llTotalSent, m_llTotalReceived);
  213. ::LogMsg(strMsg);
  214. }
  215. return __super::OnVKeyToItem(nKey, pListBox, nIndex);
  216. }
  217. LRESULT CServerDlg::OnUserInfoMsg(WPARAM wp, LPARAM lp)
  218. {
  219. info_msg* msg = (info_msg*)wp;
  220. ::LogInfoMsg(msg);
  221. return 0;
  222. }
  223. EnHandleResult CServerDlg::OnPrepareListen(SOCKET soListen)
  224. {
  225. TCHAR szAddress[40];
  226. int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
  227. USHORT usPort;
  228. m_Server->GetListenAddress(szAddress, iAddressLen, usPort);
  229. ::PostOnPrepareListen(szAddress, usPort);
  230. return HR_OK;
  231. }
  232. EnHandleResult CServerDlg::OnSend(CONNID dwConnID, const BYTE* pData, int iLength)
  233. {
  234. #ifdef _DEBUG2
  235. ::PostOnSend(dwConnID, pData, iLength);
  236. #endif
  237. #if (_WIN32_WINNT <= _WIN32_WINNT_WS03)
  238. ::InterlockedExchangeAdd((volatile LONG*)&m_llTotalSent, iLength);
  239. #else
  240. ::InterlockedExchangeAdd64(&m_llTotalSent, iLength);
  241. #endif
  242. return HR_OK;
  243. }
  244. EnHandleResult CServerDlg::OnReceive(CONNID dwConnID, const BYTE* pData, int iLength)
  245. {
  246. #ifdef _DEBUG2
  247. ::PostOnReceive(dwConnID, pData, iLength);
  248. #endif
  249. #if (_WIN32_WINNT <= _WIN32_WINNT_WS03)
  250. ::InterlockedExchangeAdd((volatile LONG*)&m_llTotalReceived, iLength);
  251. #else
  252. ::InterlockedExchangeAdd64(&m_llTotalReceived, iLength);
  253. #endif
  254. if(m_Server->Send(dwConnID, pData, iLength))
  255. return HR_OK;
  256. else
  257. return HR_ERROR;
  258. }
  259. EnHandleResult CServerDlg::OnClose(CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode)
  260. {
  261. iErrorCode == SE_OK ? ::PostOnClose(dwConnID) :
  262. ::PostOnError(dwConnID, enOperation, iErrorCode);
  263. Statistics();
  264. return HR_OK;
  265. }
  266. EnHandleResult CServerDlg::OnAccept(CONNID dwConnID, SOCKET soClient)
  267. {
  268. ::PostOnAccept2(dwConnID);
  269. return HR_OK;
  270. }
  271. EnHandleResult CServerDlg::OnHandShake(CONNID dwConnID)
  272. {
  273. if(m_lClientCount == 0)
  274. {
  275. CCriSecLock lock(m_cs);
  276. if(m_lClientCount == 0)
  277. {
  278. Reset(FALSE);
  279. }
  280. }
  281. ::InterlockedIncrement(&m_lClientCount);
  282. ::PostOnHandShake(dwConnID);
  283. return HR_OK;
  284. }
  285. EnHandleResult CServerDlg::OnShutdown()
  286. {
  287. ::PostOnShutdown();
  288. return HR_OK;
  289. }
  290. void CServerDlg::Statistics()
  291. {
  292. if(m_lClientCount > 0)
  293. {
  294. CCriSecLock lock(m_cs);
  295. if(m_lClientCount > 0)
  296. {
  297. ::InterlockedDecrement(&m_lClientCount);
  298. if(m_lClientCount == 0)
  299. {
  300. ::WaitWithMessageLoop(600L);
  301. ::PostServerStatics((LONGLONG)m_llTotalSent, (LONGLONG)m_llTotalReceived);
  302. }
  303. }
  304. }
  305. }
  306. void CServerDlg::Reset(BOOL bResetClientCount)
  307. {
  308. if(bResetClientCount)
  309. m_lClientCount = 0L;
  310. m_llTotalSent = 0L;
  311. m_llTotalReceived = 0L;
  312. }