ServerDlg.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. // ServerDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Server.h"
  5. #include "ServerDlg.h"
  6. #include "afxdialogex.h"
  7. // CServerDlg dialog
  8. const LPCTSTR CServerDlg::ADDRESS = _T("0.0.0.0");
  9. const USHORT CServerDlg::PORT = 5555;
  10. CServerDlg::CServerDlg(CWnd* pParent /*=NULL*/)
  11. : CDialogEx(CServerDlg::IDD, pParent), m_Server(this)
  12. {
  13. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  14. }
  15. void CServerDlg::DoDataExchange(CDataExchange* pDX)
  16. {
  17. CDialogEx::DoDataExchange(pDX);
  18. DDX_Control(pDX, IDC_INFO, m_Info);
  19. DDX_Control(pDX, IDC_START, m_Start);
  20. DDX_Control(pDX, IDC_STOP, m_Stop);
  21. DDX_Control(pDX, IDC_ADDRESS, m_Address);
  22. DDX_Control(pDX, IDC_CONN_ID, m_ConnID);
  23. DDX_Control(pDX, IDC_DISCONNECT, m_DisConn);
  24. }
  25. BEGIN_MESSAGE_MAP(CServerDlg, CDialogEx)
  26. ON_WM_PAINT()
  27. ON_WM_QUERYDRAGICON()
  28. ON_BN_CLICKED(IDC_START, &CServerDlg::OnBnClickedStart)
  29. ON_BN_CLICKED(IDC_STOP, &CServerDlg::OnBnClickedStop)
  30. ON_MESSAGE(USER_INFO_MSG, OnUserInfoMsg)
  31. ON_BN_CLICKED(IDC_DISCONNECT, &CServerDlg::OnBnClickedDisconnect)
  32. ON_EN_CHANGE(IDC_CONN_ID, &CServerDlg::OnEnChangeConnId)
  33. ON_WM_VKEYTOITEM()
  34. END_MESSAGE_MAP()
  35. // CServerDlg message handlers
  36. BOOL CServerDlg::OnInitDialog()
  37. {
  38. CDialogEx::OnInitDialog();
  39. // Set the icon for this dialog. The framework does this automatically
  40. // when the application's main window is not a dialog
  41. SetIcon(m_hIcon, TRUE); // Set big icon
  42. SetIcon(m_hIcon, FALSE); // Set small icon
  43. // TODO: Add extra initialization here
  44. CString strTitle;
  45. CString strOriginTitle;
  46. GetWindowText(strOriginTitle);
  47. strTitle.Format(_T("%s - (%s:%d)"), strOriginTitle, ADDRESS, PORT);
  48. SetWindowText(strTitle);
  49. ::SetMainWnd(this);
  50. ::SetInfoList(&m_Info);
  51. SetAppState(ST_STOPPED);
  52. return TRUE; // return TRUE unless you set the focus to a control
  53. }
  54. // If you add a minimize button to your dialog, you will need the code below
  55. // to draw the icon. For MFC applications using the document/view model,
  56. // this is automatically done for you by the framework.
  57. void CServerDlg::OnPaint()
  58. {
  59. if (IsIconic())
  60. {
  61. CPaintDC dc(this); // device context for painting
  62. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  63. // Center icon in client rectangle
  64. int cxIcon = GetSystemMetrics(SM_CXICON);
  65. int cyIcon = GetSystemMetrics(SM_CYICON);
  66. CRect rect;
  67. GetClientRect(&rect);
  68. int x = (rect.Width() - cxIcon + 1) / 2;
  69. int y = (rect.Height() - cyIcon + 1) / 2;
  70. // Draw the icon
  71. dc.DrawIcon(x, y, m_hIcon);
  72. }
  73. else
  74. {
  75. CDialogEx::OnPaint();
  76. }
  77. }
  78. // The system calls this function to obtain the cursor to display while the user drags
  79. // the minimized window.
  80. HCURSOR CServerDlg::OnQueryDragIcon()
  81. {
  82. return static_cast<HCURSOR>(m_hIcon);
  83. }
  84. BOOL CServerDlg::PreTranslateMessage(MSG* pMsg)
  85. {
  86. if (
  87. pMsg->message == WM_KEYDOWN
  88. &&( pMsg->wParam == VK_ESCAPE
  89. || pMsg->wParam == VK_CANCEL
  90. || pMsg->wParam == VK_RETURN
  91. ))
  92. return TRUE;
  93. return CDialog::PreTranslateMessage(pMsg);
  94. }
  95. void CServerDlg::SetAppState(EnAppState state)
  96. {
  97. m_enState = state;
  98. if(this->GetSafeHwnd() == nullptr)
  99. return;
  100. m_Start.EnableWindow(m_enState == ST_STOPPED);
  101. m_Stop.EnableWindow(m_enState == ST_STARTED);
  102. m_Address.EnableWindow(m_enState == ST_STOPPED);
  103. m_DisConn.EnableWindow(m_enState == ST_STARTED && m_ConnID.GetWindowTextLength() > 0);
  104. }
  105. void CServerDlg::OnBnClickedStart()
  106. {
  107. m_Address.GetWindowText(m_strAddress);
  108. m_strAddress.Trim();
  109. SetAppState(ST_STARTING);
  110. //m_Server->SetSocketBufferSize(64);
  111. if(m_Server->Start(ADDRESS, PORT))
  112. {
  113. ::LogServerStart(ADDRESS, PORT);
  114. SetAppState(ST_STARTED);
  115. }
  116. else
  117. {
  118. ::LogServerStartFail(m_Server->GetLastError(), m_Server->GetLastErrorDesc());
  119. SetAppState(ST_STOPPED);
  120. }
  121. }
  122. void CServerDlg::OnBnClickedStop()
  123. {
  124. SetAppState(ST_STOPPING);
  125. if(m_Server->Stop())
  126. {
  127. ::LogServerStop();
  128. SetAppState(ST_STOPPED);
  129. }
  130. else
  131. {
  132. ASSERT(FALSE);
  133. }
  134. }
  135. void CServerDlg::OnBnClickedDisconnect()
  136. {
  137. CString strConnID;
  138. m_ConnID.GetWindowText(strConnID);
  139. CONNID dwConnID = (CONNID)_ttoi(strConnID);
  140. if(m_Server->Disconnect(dwConnID))
  141. ::LogDisconnect(dwConnID);
  142. else
  143. ::LogDisconnectFail(dwConnID);
  144. }
  145. void CServerDlg::OnEnChangeConnId()
  146. {
  147. m_DisConn.EnableWindow(m_enState == ST_STARTED && m_ConnID.GetWindowTextLength() > 0);
  148. }
  149. int CServerDlg::OnVKeyToItem(UINT nKey, CListBox* pListBox, UINT nIndex)
  150. {
  151. if(nKey == 'C')
  152. pListBox->ResetContent();
  153. return __super::OnVKeyToItem(nKey, pListBox, nIndex);
  154. }
  155. LRESULT CServerDlg::OnUserInfoMsg(WPARAM wp, LPARAM lp)
  156. {
  157. info_msg* msg = (info_msg*)wp;
  158. ::LogInfoMsg(msg);
  159. return 0;
  160. }
  161. EnHandleResult CServerDlg::OnPrepareListen(SOCKET soListen)
  162. {
  163. TCHAR szAddress[40];
  164. int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
  165. USHORT usPort;
  166. m_Server->GetListenAddress(szAddress, iAddressLen, usPort);
  167. ::PostOnPrepareListen(szAddress, usPort);
  168. return HR_OK;
  169. }
  170. EnHandleResult CServerDlg::OnAccept(CONNID dwConnID, SOCKET soClient)
  171. {
  172. BOOL bPass = TRUE;
  173. TCHAR szAddress[40];
  174. int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
  175. USHORT usPort;
  176. m_Server->GetRemoteAddress(dwConnID, szAddress, iAddressLen, usPort);
  177. if(!m_strAddress.IsEmpty())
  178. {
  179. if(m_strAddress.CompareNoCase(szAddress) == 0)
  180. bPass = FALSE;
  181. }
  182. ::PostOnAccept(dwConnID, szAddress, usPort, bPass);
  183. if(bPass) m_Server->SetConnectionExtra(dwConnID, new TPkgInfo(true, sizeof(TPkgHeader)));
  184. return bPass ? HR_OK : HR_ERROR;
  185. }
  186. EnHandleResult CServerDlg::OnSend(CONNID dwConnID, const BYTE* pData, int iLength)
  187. {
  188. //static int t = 0;
  189. //if(++t % 3 == 0) return HR_ERROR;
  190. ::PostOnSend(dwConnID, pData, iLength);
  191. return HR_OK;
  192. }
  193. EnHandleResult CServerDlg::OnReceive(CONNID dwConnID, int iLength)
  194. {
  195. TPkgInfo* pInfo = FindPkgInfo(dwConnID);
  196. if(pInfo != nullptr)
  197. {
  198. int required = pInfo->length;
  199. int remain = iLength;
  200. while(remain >= required)
  201. {
  202. remain -= required;
  203. CBufferPtr buffer(required);
  204. EnFetchResult result = m_Server->Fetch(dwConnID, buffer, (int)buffer.Size());
  205. if(result == FR_OK)
  206. {
  207. if(pInfo->is_header)
  208. {
  209. TPkgHeader* pHeader = (TPkgHeader*)buffer.Ptr();
  210. TRACE("[Server] head -> seq: %d, body_len: %d\n", pHeader->seq, pHeader->body_len);
  211. required = pHeader->body_len;
  212. }
  213. else
  214. {
  215. TPkgBody* pBody = (TPkgBody*)(BYTE*)buffer;
  216. TRACE("[Server] body -> name: %s, age: %d, desc: %s\n", pBody->name, pBody->age, pBody->desc);
  217. required = sizeof(TPkgHeader);
  218. }
  219. pInfo->is_header = !pInfo->is_header;
  220. pInfo->length = required;
  221. ::PostOnReceive(dwConnID, buffer, (int)buffer.Size());
  222. if(!m_Server->Send(dwConnID, buffer, (int)buffer.Size()))
  223. return HR_ERROR;
  224. }
  225. }
  226. }
  227. return HR_OK;
  228. }
  229. EnHandleResult CServerDlg::OnClose(CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode)
  230. {
  231. iErrorCode == SE_OK ? ::PostOnClose(dwConnID) :
  232. ::PostOnError(dwConnID, enOperation, iErrorCode);
  233. RemovePkgInfo(dwConnID);
  234. return HR_OK;
  235. }
  236. EnHandleResult CServerDlg::OnShutdown()
  237. {
  238. ::PostOnShutdown();
  239. return HR_OK;
  240. }
  241. TPkgInfo* CServerDlg::FindPkgInfo(CONNID dwConnID)
  242. {
  243. PVOID pInfo = nullptr;
  244. m_Server->GetConnectionExtra(dwConnID, &pInfo);
  245. return (TPkgInfo*)pInfo;
  246. }
  247. void CServerDlg::RemovePkgInfo(CONNID dwConnID)
  248. {
  249. //CCriSecLock locallock(m_csPkgInfo);
  250. TPkgInfo* pInfo = FindPkgInfo(dwConnID);
  251. ASSERT(pInfo != nullptr);
  252. delete pInfo;
  253. }