ClientDlg.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. // ClientDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Client.h"
  5. #include "ClientDlg.h"
  6. #include "afxdialogex.h"
  7. // CClientDlg dialog
  8. #define DEFAULT_CONTENT _T("text to be sent")
  9. #define DEFAULT_ADDRESS _T("127.0.0.1")
  10. #define DEFAULT_PORT _T("5555")
  11. CClientDlg* CClientDlg::m_spThis = nullptr;
  12. CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/)
  13. : CDialogEx(CClientDlg::IDD, pParent)
  14. {
  15. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  16. m_spThis = this;
  17. // 创建监听器对象
  18. m_pListener = ::Create_HP_TcpPullClientListener();
  19. // 创建 Socket 对象
  20. m_pClient = ::Create_HP_TcpPullClient(m_pListener);
  21. // 设置 Socket 监听器回调函数
  22. ::HP_Set_FN_Client_OnConnect(m_pListener, OnConnect);
  23. ::HP_Set_FN_Client_OnSend(m_pListener, OnSend);
  24. ::HP_Set_FN_Client_OnPullReceive(m_pListener, OnReceive);
  25. ::HP_Set_FN_Client_OnClose(m_pListener, OnClose);
  26. }
  27. CClientDlg::~CClientDlg()
  28. {
  29. // 销毁 Socket 对象
  30. ::Destroy_HP_TcpPullClient(m_pClient);
  31. // 销毁监听器对象
  32. ::Destroy_HP_TcpPullClientListener(m_pListener);
  33. }
  34. void CClientDlg::DoDataExchange(CDataExchange* pDX)
  35. {
  36. CDialogEx::DoDataExchange(pDX);
  37. DDX_Control(pDX, IDC_CONTENT, m_Content);
  38. DDX_Control(pDX, IDC_SEND, m_Send);
  39. DDX_Control(pDX, IDC_INFO, m_Info);
  40. DDX_Control(pDX, IDC_ADDRESS, m_Address);
  41. DDX_Control(pDX, IDC_PORT, m_Port);
  42. DDX_Control(pDX, IDC_ASYNC, m_Async);
  43. DDX_Control(pDX, IDC_START, m_Start);
  44. DDX_Control(pDX, IDC_STOP, m_Stop);
  45. }
  46. BEGIN_MESSAGE_MAP(CClientDlg, CDialogEx)
  47. ON_WM_PAINT()
  48. ON_WM_QUERYDRAGICON()
  49. ON_BN_CLICKED(IDC_SEND, &CClientDlg::OnBnClickedSend)
  50. ON_BN_CLICKED(IDC_START, &CClientDlg::OnBnClickedStart)
  51. ON_BN_CLICKED(IDC_STOP, &CClientDlg::OnBnClickedStop)
  52. ON_MESSAGE(USER_INFO_MSG, OnUserInfoMsg)
  53. ON_WM_VKEYTOITEM()
  54. END_MESSAGE_MAP()
  55. // CClientDlg message handlers
  56. BOOL CClientDlg::OnInitDialog()
  57. {
  58. CDialogEx::OnInitDialog();
  59. // Set the icon for this dialog. The framework does this automatically
  60. // when the application's main window is not a dialog
  61. SetIcon(m_hIcon, TRUE); // Set big icon
  62. SetIcon(m_hIcon, FALSE); // Set small icon
  63. // TODO: Add extra initialization here
  64. m_Content.SetWindowText(DEFAULT_CONTENT);
  65. m_Address.SetWindowText(DEFAULT_ADDRESS);
  66. m_Port.SetWindowText(DEFAULT_PORT);
  67. m_Async.SetCheck(BST_CHECKED);
  68. ::SetMainWnd(this);
  69. ::SetInfoList(&m_Info);
  70. SetAppState(ST_STOPPED);
  71. m_bAsyncConn = FALSE;
  72. return TRUE; // return TRUE unless you set the focus to a control
  73. }
  74. // If you add a minimize button to your dialog, you will need the code below
  75. // to draw the icon. For MFC applications using the document/view model,
  76. // this is automatically done for you by the framework.
  77. void CClientDlg::OnPaint()
  78. {
  79. if (IsIconic())
  80. {
  81. CPaintDC dc(this); // device context for painting
  82. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  83. // Center icon in client rectangle
  84. int cxIcon = GetSystemMetrics(SM_CXICON);
  85. int cyIcon = GetSystemMetrics(SM_CYICON);
  86. CRect rect;
  87. GetClientRect(&rect);
  88. int x = (rect.Width() - cxIcon + 1) / 2;
  89. int y = (rect.Height() - cyIcon + 1) / 2;
  90. // Draw the icon
  91. dc.DrawIcon(x, y, m_hIcon);
  92. }
  93. else
  94. {
  95. CDialogEx::OnPaint();
  96. }
  97. }
  98. // The system calls this function to obtain the cursor to display while the user drags
  99. // the minimized window.
  100. HCURSOR CClientDlg::OnQueryDragIcon()
  101. {
  102. return static_cast<HCURSOR>(m_hIcon);
  103. }
  104. BOOL CClientDlg::PreTranslateMessage(MSG* pMsg)
  105. {
  106. if (
  107. pMsg->message == WM_KEYDOWN
  108. &&( pMsg->wParam == VK_ESCAPE
  109. || pMsg->wParam == VK_CANCEL
  110. || pMsg->wParam == VK_RETURN
  111. ))
  112. return TRUE;
  113. return CDialog::PreTranslateMessage(pMsg);
  114. }
  115. void CClientDlg::SetAppState(EnAppState state)
  116. {
  117. m_enState = state;
  118. if(this->GetSafeHwnd() == nullptr)
  119. return;
  120. m_Async.EnableWindow(m_enState == ST_STOPPED);
  121. m_Start.EnableWindow(m_enState == ST_STOPPED);
  122. m_Stop.EnableWindow(m_enState == ST_STARTED);
  123. m_Send.EnableWindow(m_enState == ST_STARTED);
  124. m_Address.EnableWindow(m_enState == ST_STOPPED);
  125. m_Port.EnableWindow(m_enState == ST_STOPPED);
  126. }
  127. void CClientDlg::OnBnClickedSend()
  128. {
  129. USES_CONVERSION;
  130. static DWORD SEQ = 0;
  131. CString strContent;
  132. m_Content.GetWindowText(strContent);
  133. smart_simple_ptr<CBufferPtr> buffer = ::GeneratePkgBuffer(++SEQ, _T("伤神小怪兽"), 23, strContent);
  134. if(::HP_Client_Send(m_pClient, buffer->Ptr(), (int)buffer->Size()))
  135. ::LogSend(::HP_Client_GetConnectionID(m_pClient), strContent);
  136. else
  137. ::LogSendFail(::HP_Client_GetConnectionID(m_pClient), ::SYS_GetLastError(), ::HP_GetSocketErrorDesc(SE_DATA_SEND));
  138. }
  139. void CClientDlg::OnBnClickedStart()
  140. {
  141. SetAppState(ST_STARTING);
  142. CString strAddress;
  143. CString strPort;
  144. m_Address.GetWindowText(strAddress);
  145. m_Port.GetWindowText(strPort);
  146. USHORT usPort = (USHORT)_ttoi(strPort);
  147. m_bAsyncConn = m_Async.GetCheck();
  148. m_pkgInfo.Reset();
  149. ::LogClientStarting(strAddress, usPort);
  150. if(::HP_Client_Start(m_pClient, strAddress, usPort, m_bAsyncConn))
  151. {
  152. }
  153. else
  154. {
  155. ::LogClientStartFail(::HP_Client_GetLastError(m_pClient), HP_Client_GetLastErrorDesc(m_pClient));
  156. SetAppState(ST_STOPPED);
  157. }
  158. }
  159. void CClientDlg::OnBnClickedStop()
  160. {
  161. SetAppState(ST_STOPPING);
  162. if(::HP_Client_Stop(m_pClient))
  163. ::LogClientStopping(::HP_Client_GetConnectionID(m_pClient));
  164. else
  165. ASSERT(FALSE);
  166. }
  167. int CClientDlg::OnVKeyToItem(UINT nKey, CListBox* pListBox, UINT nIndex)
  168. {
  169. if(nKey == 'C')
  170. pListBox->ResetContent();
  171. return __super::OnVKeyToItem(nKey, pListBox, nIndex);
  172. }
  173. LRESULT CClientDlg::OnUserInfoMsg(WPARAM wp, LPARAM lp)
  174. {
  175. info_msg* msg = (info_msg*)wp;
  176. ::LogInfoMsg(msg);
  177. return 0;
  178. }
  179. En_HP_HandleResult CClientDlg::OnConnect(HP_Client pClient)
  180. {
  181. TCHAR szAddress[40];
  182. int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
  183. USHORT usPort;
  184. ::HP_Client_GetLocalAddress(pClient, szAddress, &iAddressLen, &usPort);
  185. ::PostOnConnect(::HP_Client_GetConnectionID(pClient), szAddress, usPort);
  186. m_spThis->SetAppState(ST_STARTED);
  187. return HR_OK;
  188. }
  189. En_HP_HandleResult CClientDlg::OnSend(HP_Client pClient, const BYTE* pData, int iLength)
  190. {
  191. ::PostOnSend(::HP_Client_GetConnectionID(pClient), pData, iLength);
  192. return HR_OK;
  193. }
  194. En_HP_HandleResult CClientDlg::OnReceive(HP_Client pClient, int iLength)
  195. {
  196. int required = m_spThis->m_pkgInfo.length;
  197. int remain = iLength;
  198. while(remain >= required)
  199. {
  200. remain -= required;
  201. CBufferPtr buffer(required);
  202. En_HP_FetchResult result = ::HP_TcpPullClient_Fetch(pClient, buffer, (int)buffer.Size());
  203. if(result == FR_OK)
  204. {
  205. if(m_spThis->m_pkgInfo.is_header)
  206. {
  207. TPkgHeader* pHeader = (TPkgHeader*)buffer.Ptr();
  208. TRACE("[Client] head -> seq: %d, body_len: %d\n", pHeader->seq, pHeader->body_len);
  209. required = pHeader->body_len;
  210. }
  211. else
  212. {
  213. TPkgBody* pBody = (TPkgBody*)buffer.Ptr();
  214. TRACE("[Client] body -> name: %s, age: %d, desc: %s\n", pBody->name, pBody->age, pBody->desc);
  215. required = sizeof(TPkgHeader);
  216. }
  217. m_spThis->m_pkgInfo.is_header = !m_spThis->m_pkgInfo.is_header;
  218. m_spThis->m_pkgInfo.length = required;
  219. ::PostOnReceive(::HP_Client_GetConnectionID(pClient), buffer, (int)buffer.Size());
  220. }
  221. }
  222. return HR_OK;
  223. }
  224. En_HP_HandleResult CClientDlg::OnClose(HP_Client pClient, En_HP_SocketOperation enOperation, int iErrorCode)
  225. {
  226. iErrorCode == SE_OK ? ::PostOnClose(::HP_Client_GetConnectionID(pClient)):
  227. ::PostOnError(::HP_Client_GetConnectionID(pClient), enOperation, iErrorCode);
  228. m_spThis->SetAppState(ST_STOPPED);
  229. return HR_OK;
  230. }