NetRelay.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:3k
源码类别:

模拟服务器

开发平台:

C/C++

  1. // NetRelay.cpp: implementation of the CNetRelay class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "S3Relay.h"
  6. #include "NetRelay.h"
  7. #include "../../Multiserver/Heaven/Interface/IServer.h"
  8. //////////////////////////////////////////////////////////////////////
  9. // Construction/Destruction
  10. //////////////////////////////////////////////////////////////////////
  11. CNetRelay::CNetRelay()
  12. : m_hDataExist(NULL)
  13. {
  14. }
  15. CNetRelay::~CNetRelay()
  16. {
  17. assert(!m_hDataExist);
  18. Clearup();
  19. }
  20. DWORD CNetRelay::Main(LPVOID lpParam)
  21. {
  22. for (;;)
  23. {
  24. const HANDLE hdls[] = {m_hStop, m_hDataExist};
  25. DWORD wait = ::WaitForMultipleObjects(sizeof(hdls)/sizeof(hdls[0]), hdls, FALSE, INFINITE);
  26. if (wait != WAIT_OBJECT_0 + 1) // !(data exist)
  27. break;
  28. Breathe();
  29. }
  30. return 0;
  31. }
  32. void CNetRelay::Breathe()
  33. {
  34. Lock(); // <<<
  35. if (m_queuePckg.empty())
  36. {
  37. assert(::WaitForSingleObject(m_hDataExist, 0) == WAIT_TIMEOUT);
  38. ::ResetEvent(m_hDataExist);
  39. Unlock(); // >>>
  40. return;
  41. }
  42. else
  43. {
  44. PACKAGE pckg = m_queuePckg.front();
  45. m_queuePckg.pop_front();
  46. if (m_queuePckg.empty())
  47. ::ResetEvent(m_hDataExist);
  48. Unlock(); // >>>
  49. //send ...
  50. assert(pckg.pData && pckg.size > 0);
  51. g_pNetServer->SendPackage(pckg.idFrom, pckg.ipTo, pckg.portTo, pckg.pData, pckg.size);
  52. g_pMemory->Free(pckg.pData);
  53. in_addr ia;
  54. ia.s_addr = pckg.ipTo;
  55. gTrace("%s -- send size: %d", inet_ntoa(ia), pckg.size);
  56. }
  57. }
  58. void CNetRelay::Clearup()
  59. {
  60. for (PACKAGEQUEUE::iterator it = m_queuePckg.begin(); it != m_queuePckg.end(); it++)
  61. g_pMemory->Free((*it).pData);
  62. m_queuePckg.clear();
  63. }
  64. int CNetRelay::RelayPackage(unsigned long idFrom, DWORD ipTo, unsigned short portTo, void* pData, unsigned size)
  65. {
  66. if (pData == NULL || size < sizeof(RELAY_COMMAND))
  67. return FALSE;
  68. RELAY_COMMAND* pRelayCmd = (RELAY_COMMAND*)pData;
  69. assert(pRelayCmd->ProtocolType == c2s_relay);
  70. if (pRelayCmd->wLength < sizeof(RELAY_COMMAND) - sizeof(pRelayCmd->ProtocolType))
  71. return FALSE;
  72. PACKAGE pckg;
  73. pckg.idFrom = idFrom;
  74. pckg.ipTo = ipTo;
  75. pckg.portTo = portTo;
  76. pckg.pData = pData;
  77. pckg.size = size;
  78. Lock();
  79. m_queuePckg.push_back(pckg);
  80. if (m_hDataExist)
  81. ::SetEvent(m_hDataExist);
  82. Unlock();
  83. return TRUE;
  84. }
  85. BOOL CNetRelay::Stop()
  86. {
  87. BOOL ret = KThread::Stop();
  88. if (!ret)
  89. return FALSE;
  90. if (m_hDataExist)
  91. {
  92. ::CloseHandle(m_hDataExist);
  93. m_hDataExist = NULL;
  94. }
  95. return TRUE;
  96. }
  97. HANDLE CNetRelay::Start()
  98. {
  99. if (!m_hDataExist)
  100. m_hDataExist = ::CreateEvent(NULL, TRUE, !m_queuePckg.empty(), NULL);
  101. if (!m_hDataExist)
  102. return NULL;
  103. HANDLE hProc = KThread::Start();
  104. if (!hProc)
  105. {
  106. ::CloseHandle(m_hDataExist);
  107. m_hDataExist = NULL;
  108. return NULL;
  109. }
  110. return hProc;
  111. }