ClientDlg.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. // ClientDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Client.h"
  5. #include "ClientDlg.h"
  6. #include "afxdialogex.h"
  7. #include "../../../../Common/Src/WaitFor.h"
  8. #ifdef _WIN64
  9. #ifdef _DEBUG
  10. #pragma comment(lib, "../../../Bin/HPSocket/x64/HPSocket_UD.lib")
  11. #else
  12. #pragma comment(lib, "../../../Bin/HPSocket/x64/HPSocket_U.lib")
  13. #endif
  14. #else
  15. #ifdef _DEBUG
  16. #pragma comment(lib, "../../../Bin/HPSocket/x86/HPSocket_UD.lib")
  17. #else
  18. #pragma comment(lib, "../../../Bin/HPSocket/x86/HPSocket_U.lib")
  19. #endif
  20. #endif
  21. // CClientDlg dialog
  22. #define DEFAULT_ADDRESS _T("127.0.0.1")
  23. #define DEFAULT_PORT _T("5555")
  24. CClientDlg::CClientDlg(CWnd* pParent /*=nullptr*/)
  25. : CDialogEx(CClientDlg::IDD, pParent)
  26. {
  27. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  28. }
  29. void CClientDlg::DoDataExchange(CDataExchange* pDX)
  30. {
  31. CDialogEx::DoDataExchange(pDX);
  32. DDX_Control(pDX, IDC_INFO, m_Info);
  33. DDX_Control(pDX, IDC_ADDRESS, m_Address);
  34. DDX_Control(pDX, IDC_PORT, m_Port);
  35. DDX_Control(pDX, IDC_START, m_Start);
  36. DDX_Control(pDX, IDC_STOP, m_Stop);
  37. DDX_Control(pDX, IDC_TEST_TIMES, m_TestTimes);
  38. DDX_Control(pDX, IDC_SOCKET_COUNT, m_SocketCount);
  39. DDX_Control(pDX, IDC_DATA_LEN, m_DataLen);
  40. DDX_Control(pDX, IDC_TEST_TIMES_INTERV, m_TestInterv);
  41. }
  42. BEGIN_MESSAGE_MAP(CClientDlg, CDialogEx)
  43. ON_WM_PAINT()
  44. ON_WM_QUERYDRAGICON()
  45. ON_BN_CLICKED(IDC_START, &CClientDlg::OnBnClickedStart)
  46. ON_BN_CLICKED(IDC_STOP, &CClientDlg::OnBnClickedStop)
  47. ON_MESSAGE(USER_INFO_MSG, OnUserInfoMsg)
  48. ON_WM_VKEYTOITEM()
  49. ON_WM_CLOSE()
  50. END_MESSAGE_MAP()
  51. // CClientDlg message handlers
  52. BOOL CClientDlg::OnInitDialog()
  53. {
  54. CDialogEx::OnInitDialog();
  55. // Set the icon for this dialog. The framework does this automatically
  56. // when the application's main window is not a dialog
  57. SetIcon(m_hIcon, TRUE); // Set big icon
  58. SetIcon(m_hIcon, FALSE); // Set small icon
  59. // TODO: Add extra initialization here
  60. m_TestTimes.SetCurSel(5);
  61. m_TestInterv.SetCurSel(1);
  62. m_SocketCount.SetCurSel(5);
  63. m_DataLen.SetCurSel(5);
  64. m_Address.SetWindowText(DEFAULT_ADDRESS);
  65. m_Port.SetWindowText(DEFAULT_PORT);
  66. ::SetMainWnd(this);
  67. ::SetInfoList(&m_Info);
  68. SetAppState(ST_STOPPED);
  69. return TRUE; // return TRUE unless you set the focus to a control
  70. }
  71. void CClientDlg::OnClose()
  72. {
  73. ::SetMainWnd(nullptr);
  74. __super::OnClose();
  75. }
  76. // If you add a minimize button to your dialog, you will need the code below
  77. // to draw the icon. For MFC applications using the document/view model,
  78. // this is automatically done for you by the framework.
  79. void CClientDlg::OnPaint()
  80. {
  81. if (IsIconic())
  82. {
  83. CPaintDC dc(this); // device context for painting
  84. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  85. // Center icon in client rectangle
  86. int cxIcon = GetSystemMetrics(SM_CXICON);
  87. int cyIcon = GetSystemMetrics(SM_CYICON);
  88. CRect rect;
  89. GetClientRect(&rect);
  90. int x = (rect.Width() - cxIcon + 1) / 2;
  91. int y = (rect.Height() - cyIcon + 1) / 2;
  92. // Draw the icon
  93. dc.DrawIcon(x, y, m_hIcon);
  94. }
  95. else
  96. {
  97. CDialogEx::OnPaint();
  98. }
  99. }
  100. // The system calls this function to obtain the cursor to display while the user drags
  101. // the minimized window.
  102. HCURSOR CClientDlg::OnQueryDragIcon()
  103. {
  104. return static_cast<HCURSOR>(m_hIcon);
  105. }
  106. BOOL CClientDlg::PreTranslateMessage(MSG* pMsg)
  107. {
  108. if (
  109. pMsg->message == WM_KEYDOWN
  110. &&( pMsg->wParam == VK_ESCAPE
  111. || pMsg->wParam == VK_CANCEL
  112. || pMsg->wParam == VK_RETURN
  113. ))
  114. return TRUE;
  115. return CDialog::PreTranslateMessage(pMsg);
  116. }
  117. void CClientDlg::SetAppState(EnAppState state)
  118. {
  119. if(m_enState == state)
  120. return;
  121. m_enState = state;
  122. if(this->GetSafeHwnd() == nullptr)
  123. return;
  124. m_Start.EnableWindow(m_enState == ST_STOPPED);
  125. m_Stop.EnableWindow(m_enState == ST_STARTED);
  126. m_Address.EnableWindow(m_enState == ST_STOPPED);
  127. m_Port.EnableWindow(m_enState == ST_STOPPED);
  128. m_TestTimes.EnableWindow(m_enState == ST_STOPPED);
  129. m_TestInterv.EnableWindow(m_enState == ST_STOPPED);
  130. m_SocketCount.EnableWindow(m_enState == ST_STOPPED);
  131. m_DataLen.EnableWindow(m_enState == ST_STOPPED);
  132. }
  133. BOOL CClientDlg::CheckParams()
  134. {
  135. BOOL isOK = TRUE;
  136. if(m_strAddress.IsEmpty())
  137. {
  138. m_Address.SetFocus();
  139. isOK = FALSE;
  140. }
  141. else if(m_usPort == 0)
  142. {
  143. m_Port.SetFocus();
  144. isOK = FALSE;
  145. }
  146. else if(m_iTestTimes <= 0)
  147. {
  148. m_TestTimes.SetFocus();
  149. isOK = FALSE;
  150. }
  151. else if(m_iTestInterv < 0)
  152. {
  153. m_TestInterv.SetFocus();
  154. isOK = FALSE;
  155. }
  156. else if(m_iSocketCount <= 0)
  157. {
  158. m_SocketCount.SetFocus();
  159. isOK = FALSE;
  160. }
  161. else if(m_iDataLen <= 0)
  162. {
  163. m_DataLen.SetFocus();
  164. isOK = FALSE;
  165. }
  166. if(!isOK)
  167. MessageBox(_T("One or more settings invalid, pls check!"), _T("Params Error"), MB_OK);
  168. return isOK;
  169. }
  170. void CClientDlg::OnBnClickedStart()
  171. {
  172. CString strAddress;
  173. CString strPort;
  174. CString strTestTimes;
  175. CString strTestInterv;
  176. CString strSocketCount;
  177. CString strDataLen;
  178. m_Address.GetWindowText(strAddress);
  179. m_Port.GetWindowText(strPort);
  180. m_TestTimes.GetWindowText(strTestTimes);
  181. m_TestInterv.GetWindowText(strTestInterv);
  182. m_SocketCount.GetWindowText(strSocketCount);
  183. m_DataLen.GetWindowText(strDataLen);
  184. m_strAddress = strAddress.Trim();
  185. m_usPort = (USHORT)_ttoi(strPort);
  186. m_iTestTimes = _ttoi(strTestTimes);
  187. m_iTestInterv = _ttoi(strTestInterv);
  188. m_iSocketCount = _ttoi(strSocketCount);
  189. m_iDataLen = _ttoi(strDataLen);
  190. if(!CheckParams())
  191. return;
  192. SetAppState(ST_STARTING);
  193. m_dwBeginTickCount = 0;
  194. m_dwTimeconsuming = 0;
  195. m_llTotalReceived = 0;
  196. m_llTotalSent = 0;
  197. m_llExpectReceived = (LONGLONG)m_iTestTimes * (LONGLONG)m_iSocketCount * (LONGLONG)m_iDataLen;
  198. m_vtClients.Clear();
  199. for(int i = 0; i < m_iSocketCount; i++)
  200. {
  201. smart_simple_ptr<CTcpClientPtr> pSocket = new CTcpClientPtr(this);
  202. if((*pSocket)->Start(m_strAddress, m_usPort))
  203. m_vtClients->push_back(pSocket.release());
  204. else
  205. {
  206. ::LogClientStartFail((*pSocket)->GetLastError(), (*pSocket)->GetLastErrorDesc());
  207. m_vtClients.Clear();
  208. SetAppState(ST_STOPPED);
  209. return;
  210. }
  211. }
  212. ::LogClientStart(m_strAddress, m_usPort);
  213. DWORD dwSendDelay = 3;
  214. CString strMsg;
  215. strMsg.Format(_T(" *** willing to send data after %d seconds ..."), dwSendDelay);
  216. ::LogMsg(strMsg);
  217. ::WaitWithMessageLoop(dwSendDelay * 1000);
  218. m_sendBuffer.Malloc(m_iDataLen, true);
  219. SetAppState(ST_STARTED);
  220. ::LogMsg(_T(" *** Go Now !"));
  221. m_dwBeginTickCount = ::TimeGetTime();
  222. BOOL bTerminated = FALSE;
  223. for(int i = 0; i < m_iTestTimes; i++)
  224. {
  225. for(int j = 0; j < m_iSocketCount; j++)
  226. {
  227. CTcpClientPtr* pSocket = m_vtClients[j];
  228. if(!(*pSocket)->Send(m_sendBuffer, (int)m_sendBuffer.Size()))
  229. {
  230. ::LogClientSendFail(i + 1, j + 1, ::SYS_GetLastError(), ::HP_GetSocketErrorDesc(SE_DATA_SEND));
  231. bTerminated = TRUE;
  232. break;
  233. }
  234. }
  235. if(bTerminated)
  236. break;
  237. if(m_iTestInterv > 0 && i + 1 < m_iTestTimes)
  238. ::WaitWithMessageLoop(m_iTestInterv);
  239. }
  240. m_sendBuffer.Free();
  241. }
  242. void CClientDlg::OnBnClickedStop()
  243. {
  244. SetAppState(ST_STOPPING);
  245. for(size_t i = 0; i < m_vtClients.Size(); i++)
  246. {
  247. CTcpClientPtr* pSocket = m_vtClients[i];
  248. if((*pSocket)->Stop())
  249. ::LogClientStopping((DWORD)i + 1);
  250. //else
  251. // ASSERT(FALSE);
  252. }
  253. ::WaitWithMessageLoop(100L);
  254. CString strMsg;
  255. strMsg.Format( _T(" *** Summary: expect - %lld, send - %lld, recv - %lld"),
  256. m_llExpectReceived, m_llTotalSent, m_llTotalReceived);
  257. ::LogMsg(strMsg);
  258. if(m_llExpectReceived == m_llTotalSent && m_llTotalSent == m_llTotalReceived)
  259. strMsg.Format(_T(" *** Success: time consuming - %u millisecond !"), m_dwTimeconsuming);
  260. else
  261. strMsg.Format(_T(" *** Fail: manual terminated ? (or data lost)"));
  262. ::LogMsg(strMsg);
  263. SetAppState(ST_STOPPED);
  264. }
  265. int CClientDlg::OnVKeyToItem(UINT nKey, CListBox* pListBox, UINT nIndex)
  266. {
  267. if(nKey == 'C')
  268. pListBox->ResetContent();
  269. return __super::OnVKeyToItem(nKey, pListBox, nIndex);
  270. }
  271. LRESULT CClientDlg::OnUserInfoMsg(WPARAM wp, LPARAM lp)
  272. {
  273. info_msg* msg = (info_msg*)wp;
  274. ::LogInfoMsg(msg);
  275. return 0;
  276. }
  277. EnHandleResult CClientDlg::OnPrepareConnect(IClient* pClient, SOCKET socket)
  278. {
  279. return HR_OK;
  280. }
  281. EnHandleResult CClientDlg::OnSend(IClient* pClient, const BYTE* pData, int iLength)
  282. {
  283. #ifdef _DEBUG2
  284. ::PostOnSend(pClient->GetConnectionID(), pData, iLength);
  285. #endif
  286. #if (_WIN32_WINNT <= _WIN32_WINNT_WS03)
  287. ::InterlockedExchangeAdd((volatile LONG*)&m_llTotalSent, iLength);
  288. #else
  289. ::InterlockedExchangeAdd64(&m_llTotalSent, iLength);
  290. #endif
  291. return HR_OK;
  292. }
  293. EnHandleResult CClientDlg::OnReceive(IClient* pClient, const BYTE* pData, int iLength)
  294. {
  295. #ifdef _DEBUG2
  296. ::PostOnReceive(pClient->GetConnectionID(), pData, iLength);
  297. #endif
  298. #if (_WIN32_WINNT <= _WIN32_WINNT_WS03)
  299. ::InterlockedExchangeAdd((volatile LONG*)&m_llTotalReceived, iLength);
  300. #else
  301. ::InterlockedExchangeAdd64(&m_llTotalReceived, iLength);
  302. #endif
  303. if(m_llTotalReceived == m_llExpectReceived)
  304. {
  305. m_dwTimeconsuming = ::GetTimeGap32(m_dwBeginTickCount);
  306. ::PostTimeConsuming(m_dwTimeconsuming);
  307. }
  308. ASSERT(m_llTotalReceived <= m_llExpectReceived);
  309. return HR_OK;
  310. }
  311. EnHandleResult CClientDlg::OnClose(IClient* pClient, EnSocketOperation enOperation, int iErrorCode)
  312. {
  313. iErrorCode == SE_OK ? ::PostOnClose(pClient->GetConnectionID()) :
  314. ::PostOnError(pClient->GetConnectionID(), enOperation, iErrorCode) ;
  315. return HR_OK;
  316. }
  317. EnHandleResult CClientDlg::OnConnect(IClient* pClient)
  318. {
  319. ::LogOnConnect2(pClient->GetConnectionID());
  320. return HR_OK;
  321. }