ClientDlg.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  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. #define LOCAL_ADDRESS _T("0.0.0.0")
  12. // link: ..\..\Bin\HPSocket\x86\HPSocket_UD.lib
  13. #ifdef _WIN64
  14. #ifdef _DEBUG
  15. #pragma comment(lib, "../../../Bin/HPSocket4C/x64/HPSocket4C_UD.lib")
  16. #else
  17. #pragma comment(lib, "../../../Bin/HPSocket4C/x64/HPSocket4C_U.lib")
  18. #endif
  19. #else
  20. #ifdef _DEBUG
  21. #pragma comment(lib, "../../../Bin/HPSocket4C/x86/HPSocket4C_UD.lib")
  22. #else
  23. #pragma comment(lib, "../../../Bin/HPSocket4C/x86/HPSocket4C_U.lib")
  24. #endif
  25. #endif
  26. CClientDlg* CClientDlg::m_spThis = nullptr;
  27. HP_TcpPullAgent CClientDlg::m_spAgent = nullptr;
  28. HP_TcpPullAgentListener CClientDlg::m_spListener = nullptr;
  29. CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/)
  30. : CDialogEx(CClientDlg::IDD, pParent)
  31. {
  32. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  33. m_spThis = this;
  34. // 创建监听器对象
  35. m_spListener = ::Create_HP_TcpPullAgentListener();
  36. // 创建 Socket 对象
  37. m_spAgent = ::Create_HP_TcpPullAgent(m_spListener);
  38. // 设置 Socket 监听器回调函数
  39. ::HP_Set_FN_Agent_OnConnect(m_spListener, OnConnect);
  40. ::HP_Set_FN_Agent_OnSend(m_spListener, OnSend);
  41. ::HP_Set_FN_Agent_OnPullReceive(m_spListener, OnReceive);
  42. ::HP_Set_FN_Agent_OnClose(m_spListener, OnClose);
  43. ::HP_Set_FN_Agent_OnShutdown(m_spListener, OnShutdown);
  44. }
  45. CClientDlg::~CClientDlg()
  46. {
  47. // 销毁 Socket 对象
  48. ::Destroy_HP_TcpPullAgent(m_spAgent);
  49. // 销毁监听器对象
  50. ::Destroy_HP_TcpPullAgentListener(m_spListener);
  51. }
  52. void CClientDlg::DoDataExchange(CDataExchange* pDX)
  53. {
  54. CDialogEx::DoDataExchange(pDX);
  55. DDX_Control(pDX, IDC_CONTENT, m_Content);
  56. DDX_Control(pDX, IDC_SEND, m_Send);
  57. DDX_Control(pDX, IDC_INFO, m_Info);
  58. DDX_Control(pDX, IDC_ADDRESS, m_Address);
  59. DDX_Control(pDX, IDC_PORT, m_Port);
  60. DDX_Control(pDX, IDC_START, m_Start);
  61. DDX_Control(pDX, IDC_CONNECT, m_Connect);
  62. DDX_Control(pDX, IDC_STOP, m_Stop);
  63. }
  64. BEGIN_MESSAGE_MAP(CClientDlg, CDialogEx)
  65. ON_WM_PAINT()
  66. ON_WM_QUERYDRAGICON()
  67. ON_BN_CLICKED(IDC_SEND, &CClientDlg::OnBnClickedSend)
  68. ON_BN_CLICKED(IDC_START, &CClientDlg::OnBnClickedStart)
  69. ON_BN_CLICKED(IDC_CONNECT, &CClientDlg::OnBnClickedConnect)
  70. ON_BN_CLICKED(IDC_STOP, &CClientDlg::OnBnClickedStop)
  71. ON_MESSAGE(USER_INFO_MSG, OnUserInfoMsg)
  72. ON_WM_VKEYTOITEM()
  73. END_MESSAGE_MAP()
  74. // CClientDlg message handlers
  75. BOOL CClientDlg::OnInitDialog()
  76. {
  77. CDialogEx::OnInitDialog();
  78. // Set the icon for this dialog. The framework does this automatically
  79. // when the application's main window is not a dialog
  80. SetIcon(m_hIcon, TRUE); // Set big icon
  81. SetIcon(m_hIcon, FALSE); // Set small icon
  82. // TODO: Add extra initialization here
  83. m_Content.SetWindowText(DEFAULT_CONTENT);
  84. m_Address.SetWindowText(DEFAULT_ADDRESS);
  85. m_Port.SetWindowText(DEFAULT_PORT);
  86. ::SetMainWnd(this);
  87. ::SetInfoList(&m_Info);
  88. SetAppState(ST_STOPPED);
  89. return TRUE; // return TRUE unless you set the focus to a control
  90. }
  91. // If you add a minimize button to your dialog, you will need the code below
  92. // to draw the icon. For MFC applications using the document/view model,
  93. // this is automatically done for you by the framework.
  94. void CClientDlg::OnPaint()
  95. {
  96. if (IsIconic())
  97. {
  98. CPaintDC dc(this); // device context for painting
  99. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  100. // Center icon in client rectangle
  101. int cxIcon = GetSystemMetrics(SM_CXICON);
  102. int cyIcon = GetSystemMetrics(SM_CYICON);
  103. CRect rect;
  104. GetClientRect(&rect);
  105. int x = (rect.Width() - cxIcon + 1) / 2;
  106. int y = (rect.Height() - cyIcon + 1) / 2;
  107. // Draw the icon
  108. dc.DrawIcon(x, y, m_hIcon);
  109. }
  110. else
  111. {
  112. CDialogEx::OnPaint();
  113. }
  114. }
  115. // The system calls this function to obtain the cursor to display while the user drags
  116. // the minimized window.
  117. HCURSOR CClientDlg::OnQueryDragIcon()
  118. {
  119. return static_cast<HCURSOR>(m_hIcon);
  120. }
  121. BOOL CClientDlg::PreTranslateMessage(MSG* pMsg)
  122. {
  123. if (
  124. pMsg->message == WM_KEYDOWN
  125. &&( pMsg->wParam == VK_ESCAPE
  126. || pMsg->wParam == VK_CANCEL
  127. || pMsg->wParam == VK_RETURN
  128. ))
  129. return TRUE;
  130. return CDialog::PreTranslateMessage(pMsg);
  131. }
  132. void CClientDlg::SetAppState(EnAppState state)
  133. {
  134. m_enState = state;
  135. if(this->GetSafeHwnd() == nullptr)
  136. return;
  137. m_Connect.SetWindowText(m_enState == ST_CONNECTED ? _T("Dis Connect") : _T("Connect"));
  138. m_Start.EnableWindow(m_enState == ST_STOPPED);
  139. m_Connect.EnableWindow(m_enState == ST_STARTED || m_enState == ST_CONNECTED);
  140. m_Stop.EnableWindow(m_enState == ST_STARTED || m_enState == ST_CONNECTED);
  141. m_Send.EnableWindow(m_enState == ST_CONNECTED);
  142. m_Address.EnableWindow(m_enState == ST_STOPPED);
  143. m_Port.EnableWindow(m_enState == ST_STOPPED);
  144. }
  145. void CClientDlg::OnBnClickedSend()
  146. {
  147. USES_CONVERSION;
  148. static DWORD SEQ = 0;
  149. CString strContent;
  150. m_Content.GetWindowText(strContent);
  151. smart_simple_ptr<CBufferPtr> buffer = ::GeneratePkgBuffer(++SEQ, _T("伤神小怪兽"), 23, strContent);
  152. if(::HP_Agent_Send(m_spAgent, m_dwConnID, buffer->Ptr(), (int)buffer->Size()))
  153. ::LogSend(m_dwConnID, strContent);
  154. else
  155. ::LogSendFail(m_dwConnID, SE_DATA_SEND, ::HP_GetSocketErrorDesc(SE_DATA_SEND));
  156. }
  157. void CClientDlg::OnBnClickedStart()
  158. {
  159. SetAppState(ST_STARTING);
  160. CString strPort;
  161. m_Address.GetWindowText(m_strAddress);
  162. m_Port.GetWindowText(strPort);
  163. m_usPort = (USHORT)_ttoi(strPort);
  164. m_dwConnID = 0;
  165. m_pkgInfo.Reset();
  166. ::LogClientStarting(m_strAddress, m_usPort);
  167. ::HP_TcpAgent_SetReuseAddress(m_spAgent, TRUE);
  168. if(::HP_Agent_Start(m_spAgent, LOCAL_ADDRESS, FALSE))
  169. {
  170. SetAppState(ST_STARTED);
  171. }
  172. else
  173. {
  174. ::LogClientStartFail(::SYS_GetLastError(), ::HP_GetSocketErrorDesc(SE_DATA_SEND));
  175. SetAppState(ST_STOPPED);
  176. }
  177. }
  178. void CClientDlg::OnBnClickedConnect()
  179. {
  180. EnAppState enState = m_enState;
  181. SetAppState(ST_CONNECTING);
  182. if(enState != ST_CONNECTED)
  183. {
  184. if(::HP_Agent_Connect(m_spAgent, m_strAddress, m_usPort, &m_dwConnID))
  185. {
  186. }
  187. else
  188. {
  189. ::LogClientStartFail(::SYS_GetLastError(), ::HP_GetSocketErrorDesc(SE_CONNECT_SERVER));
  190. SetAppState(ST_STARTED);
  191. }
  192. }
  193. else
  194. {
  195. ::HP_Agent_Disconnect(m_spAgent, m_dwConnID, FALSE);
  196. }
  197. }
  198. void CClientDlg::OnBnClickedStop()
  199. {
  200. SetAppState(ST_STOPPING);
  201. if(!::HP_Agent_Stop(m_spAgent))
  202. ASSERT(FALSE);
  203. }
  204. int CClientDlg::OnVKeyToItem(UINT nKey, CListBox* pListBox, UINT nIndex)
  205. {
  206. if(nKey == 'C')
  207. pListBox->ResetContent();
  208. return __super::OnVKeyToItem(nKey, pListBox, nIndex);
  209. }
  210. LRESULT CClientDlg::OnUserInfoMsg(WPARAM wp, LPARAM lp)
  211. {
  212. info_msg* msg = (info_msg*)wp;
  213. ::LogInfoMsg(msg);
  214. return 0;
  215. }
  216. En_HP_HandleResult CClientDlg::OnConnect(HP_CONNID m_dwConnID)
  217. {
  218. TCHAR szAddress[40];
  219. int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
  220. USHORT usPort;
  221. ::HP_Agent_GetLocalAddress(m_spAgent, m_dwConnID, szAddress, &iAddressLen, &usPort);
  222. ::PostOnConnect(m_dwConnID, szAddress, usPort);
  223. m_spThis->SetAppState(ST_CONNECTED);
  224. return HR_OK;
  225. }
  226. En_HP_HandleResult CClientDlg::OnSend(HP_CONNID m_dwConnID, const BYTE* pData, int iLength)
  227. {
  228. ::PostOnSend(m_dwConnID, pData, iLength);
  229. return HR_OK;
  230. }
  231. En_HP_HandleResult CClientDlg::OnReceive(HP_CONNID m_dwConnID, int iLength)
  232. {
  233. int required = m_spThis->m_pkgInfo.length;
  234. int remain = iLength;
  235. while(remain >= required)
  236. {
  237. remain -= required;
  238. CBufferPtr buffer(required);
  239. En_HP_FetchResult result = ::HP_TcpPullAgent_Fetch(m_spAgent, m_dwConnID, buffer, (int)buffer.Size());
  240. if(result == FR_OK)
  241. {
  242. if(m_spThis->m_pkgInfo.is_header)
  243. {
  244. TPkgHeader* pHeader = (TPkgHeader*)buffer.Ptr();
  245. TRACE("[Agent] head -> seq: %d, body_len: %d\n", pHeader->seq, pHeader->body_len);
  246. required = pHeader->body_len;
  247. }
  248. else
  249. {
  250. TPkgBody* pBody = (TPkgBody*)buffer.Ptr();
  251. TRACE("[Agent] body -> name: %s, age: %d, desc: %s\n", pBody->name, pBody->age, pBody->desc);
  252. required = sizeof(TPkgHeader);
  253. }
  254. m_spThis->m_pkgInfo.is_header = !m_spThis->m_pkgInfo.is_header;
  255. m_spThis->m_pkgInfo.length = required;
  256. ::PostOnReceive(m_dwConnID, buffer, (int)buffer.Size());
  257. }
  258. }
  259. return HR_OK;
  260. }
  261. En_HP_HandleResult CClientDlg::OnClose(HP_CONNID m_dwConnID, En_HP_SocketOperation enOperation, int iErrorCode)
  262. {
  263. iErrorCode == SE_OK ? ::PostOnClose(m_dwConnID):
  264. ::PostOnError(m_dwConnID, enOperation, iErrorCode);
  265. m_spThis->SetAppState(ST_STARTED);
  266. return HR_OK;
  267. }
  268. En_HP_HandleResult CClientDlg::OnShutdown()
  269. {
  270. ::PostOnShutdown();
  271. m_spThis->SetAppState(ST_STOPPED);
  272. return HR_OK;
  273. }