ClientDlg.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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<CUdpClientPtr> pSocket = new CUdpClientPtr(this);
  202. //(*pSocket)->SetDetectAttempts(0);
  203. if((*pSocket)->Start(m_strAddress, m_usPort))
  204. m_vtClients->push_back(pSocket.release());
  205. else
  206. {
  207. ::LogClientStartFail((*pSocket)->GetLastError(), (*pSocket)->GetLastErrorDesc());
  208. m_vtClients.Clear();
  209. SetAppState(ST_STOPPED);
  210. return;
  211. }
  212. }
  213. ::LogClientStart(m_strAddress, m_usPort);
  214. DWORD dwSendDelay = 3;
  215. CString strMsg;
  216. strMsg.Format(_T(" *** willing to send data after %d seconds ..."), dwSendDelay);
  217. ::LogMsg(strMsg);
  218. ::WaitWithMessageLoop(dwSendDelay * 1000);
  219. m_sendBuffer.Malloc(m_iDataLen, true);
  220. SetAppState(ST_STARTED);
  221. ::LogMsg(_T(" *** Go Now !"));
  222. m_dwBeginTickCount = ::TimeGetTime();
  223. BOOL bTerminated = FALSE;
  224. for(int i = 0; i < m_iTestTimes; i++)
  225. {
  226. for(int j = 0; j < m_iSocketCount; j++)
  227. {
  228. CUdpClientPtr* pSocket = m_vtClients[j];
  229. if(!(*pSocket)->Send(m_sendBuffer, (int)m_sendBuffer.Size()))
  230. {
  231. ::LogClientSendFail(i + 1, j + 1, ::SYS_GetLastError(), ::HP_GetSocketErrorDesc(SE_DATA_SEND));
  232. bTerminated = TRUE;
  233. break;
  234. }
  235. }
  236. if(bTerminated)
  237. break;
  238. if(m_iTestInterv > 0 && i + 1 < m_iTestTimes)
  239. ::WaitWithMessageLoop(m_iTestInterv);
  240. }
  241. m_sendBuffer.Free();
  242. }
  243. void CClientDlg::OnBnClickedStop()
  244. {
  245. SetAppState(ST_STOPPING);
  246. for(size_t i = 0; i < m_vtClients.Size(); i++)
  247. {
  248. CUdpClientPtr* pSocket = m_vtClients[i];
  249. if((*pSocket)->Stop())
  250. ::LogClientStopping((DWORD)i + 1);
  251. //else
  252. // ASSERT(FALSE);
  253. }
  254. ::WaitWithMessageLoop(100L);
  255. CString strMsg;
  256. strMsg.Format( _T(" *** Summary: expect - %lld, send - %lld, recv - %lld"),
  257. m_llExpectReceived, m_llTotalSent, m_llTotalReceived);
  258. ::LogMsg(strMsg);
  259. if(m_llExpectReceived == m_llTotalSent && m_llTotalSent == m_llTotalReceived)
  260. strMsg.Format(_T(" *** Success: time consuming - %u millisecond !"), m_dwTimeconsuming);
  261. else
  262. strMsg.Format(_T(" *** Fail: manual terminated ? (or data lost)"));
  263. ::LogMsg(strMsg);
  264. SetAppState(ST_STOPPED);
  265. }
  266. int CClientDlg::OnVKeyToItem(UINT nKey, CListBox* pListBox, UINT nIndex)
  267. {
  268. if(nKey == 'C')
  269. pListBox->ResetContent();
  270. return __super::OnVKeyToItem(nKey, pListBox, nIndex);
  271. }
  272. LRESULT CClientDlg::OnUserInfoMsg(WPARAM wp, LPARAM lp)
  273. {
  274. info_msg* msg = (info_msg*)wp;
  275. ::LogInfoMsg(msg);
  276. return 0;
  277. }
  278. EnHandleResult CClientDlg::OnPrepareConnect(IClient* pClient, SOCKET socket)
  279. {
  280. return HR_OK;
  281. }
  282. EnHandleResult CClientDlg::OnSend(IClient* pClient, const BYTE* pData, int iLength)
  283. {
  284. #ifdef _DEBUG
  285. ::PostOnSend(pClient->GetConnectionID(), pData, iLength);
  286. #endif
  287. #if (_WIN32_WINNT <= _WIN32_WINNT_WS03)
  288. ::InterlockedExchangeAdd((volatile LONG*)&m_llTotalSent, iLength);
  289. #else
  290. ::InterlockedExchangeAdd64(&m_llTotalSent, iLength);
  291. #endif
  292. return HR_OK;
  293. }
  294. EnHandleResult CClientDlg::OnReceive(IClient* pClient, const BYTE* pData, int iLength)
  295. {
  296. #ifdef _DEBUG
  297. ::PostOnReceive(pClient->GetConnectionID(), pData, iLength);
  298. #endif
  299. #if (_WIN32_WINNT <= _WIN32_WINNT_WS03)
  300. ::InterlockedExchangeAdd((volatile LONG*)&m_llTotalReceived, iLength);
  301. #else
  302. ::InterlockedExchangeAdd64(&m_llTotalReceived, iLength);
  303. #endif
  304. if(m_llTotalReceived == m_llExpectReceived)
  305. {
  306. m_dwTimeconsuming = ::GetTimeGap32(m_dwBeginTickCount);
  307. ::PostTimeConsuming(m_dwTimeconsuming);
  308. }
  309. ASSERT(m_llTotalReceived <= m_llExpectReceived);
  310. return HR_OK;
  311. }
  312. EnHandleResult CClientDlg::OnClose(IClient* pClient, EnSocketOperation enOperation, int iErrorCode)
  313. {
  314. iErrorCode == SE_OK ? ::PostOnClose(pClient->GetConnectionID()) :
  315. ::PostOnError(pClient->GetConnectionID(), enOperation, iErrorCode) ;
  316. return HR_OK;
  317. }
  318. EnHandleResult CClientDlg::OnConnect(IClient* pClient)
  319. {
  320. ::LogOnConnect2(pClient->GetConnectionID());
  321. return HR_OK;
  322. }