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

模拟服务器

开发平台:

C/C++

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //  
  3. //  FileName    :   PingThread.cpp
  4. //  Version     :   1.0
  5. //  Creater     :   Linsuyi
  6. //  Date        :   2002-01-10  10:30:13
  7. //  Comment     :   Tcp/ip ping thread source file
  8. //  
  9. ////////////////////////////////////////////////////////////////////////////////
  10. #include "Stdafx.h"
  11. #include "PingThread.h"
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. CPingThread::CPingThread()
  16. {
  17.     m_nRepeatCount  = PINGTHREAD_PINGCOUNT;
  18.     m_nPingTimeOut  = DEFAULT_PING_TIMEOUT;
  19.     
  20.     m_ulContextWith = 0;
  21.     
  22.     m_hPingThread = NULL;
  23.     m_ulPingThreadId = 0;
  24.     
  25.     m_piCallback    = NULL;
  26. }
  27. CPingThread::~CPingThread()
  28. {
  29. }
  30. void CPingThread::SetSplitTimes(int nTimes)
  31. {
  32.     if (nTimes <= 0)
  33.         nTimes = 1;
  34.     else if (nTimes > 10)
  35.         nTimes = 10;
  36.     
  37.     m_nRepeatCount = nTimes;
  38. }
  39. void CPingThread::SetTimeOut(int nTimeOut)
  40. {
  41.     m_nPingTimeOut = nTimeOut;
  42. }
  43. void CPingThread::SetContext(ULONG ulContext)
  44. {
  45.     m_ulContextWith = ulContext;
  46. }
  47. void CPingThread::SetCallback(IKPingCallback *piCallback)
  48. {
  49.     m_piCallback = piCallback;
  50. }
  51. int CPingThread::StartPingThread()
  52. {
  53.     int nResult = false;
  54.     
  55.     ASSERT(NULL == m_hPingThread);
  56.     
  57.     ASSERT(m_piCallback != NULL);
  58.     
  59.     m_ulPingThreadId = 0;
  60.     
  61.     m_hPingThread = ::CreateThread(
  62.         NULL,
  63.         0,
  64.         (LPTHREAD_START_ROUTINE)&PingThreadProc,
  65.         (LPVOID)this,
  66.         0,
  67.         &m_ulPingThreadId
  68.     );
  69.     if (NULL == m_hPingThread)
  70.         goto Exit0;
  71.     
  72.     TRACE1("Ping Thread Start: 0x%xn", m_ulPingThreadId);
  73.     
  74.     nResult = true;
  75.     
  76. Exit0:
  77.     return nResult;
  78. }
  79. int CPingThread::StopPingThread(int nForceStop)
  80. {
  81.     int nResult = false;
  82.     
  83.     if (m_hPingThread  != NULL)
  84.     {
  85.         ULONG ulRetCode = 0;
  86.         
  87.         ulRetCode = ::WaitForSingleObject(m_hPingThread, 0);  // -1
  88.         if (ulRetCode != WAIT_OBJECT_0)
  89.         {
  90.             int nRetCode = false;
  91.             
  92.             ASSERT(FALSE);
  93.             
  94.             if (!nForceStop)
  95.                 goto Exit0;
  96.             
  97.             nRetCode = ::TerminateThread(m_hPingThread, -1);
  98.             ASSERT(nRetCode);
  99.             
  100.             TRACE1("Ping Thread Terminate: 0x%xn", m_ulPingThreadId);
  101.         }
  102.         
  103.         TRACE1("Ping Thread Stopped: 0x%xn", m_ulPingThreadId);
  104.         m_ulPingThreadId = 0;
  105.         
  106.         ::CloseHandle(m_hPingThread);
  107.         m_hPingThread = NULL;
  108.     }
  109.     
  110.     nResult = true;
  111.     
  112. Exit0:
  113.     return nResult;
  114. }
  115. HANDLE CPingThread::GetThreadHandle()
  116. {
  117.     return m_hPingThread;
  118. }
  119. int CPingThread::OnPingStatus(int nOccurEvent)
  120. {
  121.     int nResult = CPingSocket::OnPingStatus(nOccurEvent);
  122.     ULONG ulRetCode = 0;
  123.     
  124.     switch (nOccurEvent)
  125.     {
  126.     case PINGEVENT_TESTBREAK:
  127.         nResult = DoStatusNotify(PINGEVENT_THREADIDLE, (ULONG)this);
  128.         nResult = !nResult;
  129.         break;
  130.         
  131.     case PINGEVENT_REPEAT:
  132.         nResult = DoStatusNotify(PINGEVENT_THREADEXIT, (ULONG)this);
  133.         nResult = !nResult;
  134.         break;
  135.         
  136.     case PINGEVENT_THREADEXIT:
  137.         nResult = DoStatusNotify(nOccurEvent, (ULONG)this);
  138.         break;
  139.         
  140.     case PINGEVENT_OCCURSTART:
  141.     case PINGEVENT_OCCURERROR:
  142.     case PINGEVENT_HOSTNOTFOUND:
  143.     case PINGEVENT_TIMEOUT:
  144.         nResult = DoStatusNotify(nOccurEvent, (ULONG)this);
  145.         break;
  146.         
  147.     default:
  148.         nResult = true;
  149.         break;
  150.     }
  151.     
  152.     return nResult;
  153. }
  154. int CPingThread::DoStatusNotify(ULONG ulOccurEvent, ULONG ulOccurParam)
  155. {
  156.     int nResult = 0;
  157.     ASSERT(m_piCallback != NULL);
  158.     
  159.     if (m_piCallback != NULL)
  160.     {
  161.         nResult = m_piCallback->PingStatus(
  162.             m_ulContextWith,
  163.             ulOccurEvent,
  164.             ulOccurParam
  165.         );
  166.     }
  167.     
  168.     return nResult;
  169. }
  170. ULONG CPingThread::MainExecution()
  171. {
  172.     ULONG ulResult = 0;
  173.     
  174.     int nRetCode = false;
  175.     int nPingStop = false;
  176.     ULONG ulContextWith;
  177.     
  178.     int   nPingLeft;
  179.     int   nPingTime;
  180.     int   nPingUsedTime;
  181.     char  szPingUrl[PINGTHREAD_URLMAXLENGTH];
  182.     
  183.     nRetCode = CPingSocket::Create();
  184.     if (!nRetCode)
  185.         goto Exit0;
  186.     
  187.     while (!nPingStop)
  188.     {
  189.         nRetCode = OnPingStatus(PINGEVENT_THREADEXIT);
  190.         if (nRetCode)
  191.         {
  192.             nPingStop = true;
  193.             break;
  194.         }
  195.         
  196.         ulContextWith = 0;
  197.         ZeroMemory(szPingUrl, sizeof(szPingUrl));
  198.         
  199.         nRetCode = m_piCallback->GetNextUrl(
  200.             &ulContextWith,
  201.             sizeof(szPingUrl),
  202.             szPingUrl
  203.         );
  204.         if (nRetCode <= 0)
  205.         {
  206.             if (0 == nRetCode)
  207.             {
  208.                 ASSERT(FALSE);
  209.                 continue;
  210.             }
  211.             
  212.             nRetCode = OnPingStatus(PINGEVENT_THREADEXIT);
  213.             if (nRetCode)
  214.             {
  215.                 nPingStop = true;
  216.                 break;
  217.             }
  218.             
  219.             continue;
  220.         }
  221.         
  222.         SetContext(ulContextWith);
  223.         
  224.         OnPingStatus(PINGEVENT_OCCURSTART);
  225.         
  226.         nPingLeft = m_nRepeatCount;
  227.         nPingUsedTime = 0;
  228.         
  229.         while (nPingLeft-- > 0)
  230.         {
  231.             nPingTime = m_nPingTimeOut;
  232.             
  233.             nRetCode = PingToAddress(szPingUrl, nPingTime);
  234.             if (PINGRESULT_SUCCESS == nRetCode)
  235.             {
  236.                 nPingUsedTime += nPingTime;
  237.                 
  238.                 DoStatusNotify(
  239.                     PINGEVENT_OCCUROVER,
  240.                     nPingUsedTime
  241.                 );
  242.                 continue;
  243.             }
  244.             if (PINGRESULT_TIMEOUT == nRetCode)
  245.             {
  246.                 nPingUsedTime += nPingTime;
  247.                 
  248.                 DoStatusNotify(
  249.                     PINGEVENT_TIMEOUT,
  250.                     nPingUsedTime
  251.                 );
  252.                 continue;
  253.             }
  254.             
  255.             break;
  256.         }
  257.         
  258.         if (PINGRESULT_TESTBREAK == nRetCode)
  259.             continue;
  260.         
  261.         // DoStatusNotify(
  262.         //     PINGEVENT_OCCUROVER,
  263.         //     nPingUsedTime
  264.         // );
  265.         
  266.         ulResult++;
  267.     }
  268.     
  269. Exit0:
  270.     nRetCode = CPingSocket::IsSocketOK();
  271.     if (nRetCode)
  272.         CPingSocket::Destroy();
  273.     
  274.     return ulResult;
  275. }
  276. ULONG WINAPI CPingThread::PingThreadProc(LPVOID lpThisParam)
  277. {
  278.     ULONG ulResult = 0;
  279.     CPingThread *pThis = (CPingThread *)lpThisParam;
  280.     
  281.     ASSERT_POINTER(pThis, CPingThread);
  282.     
  283.     ASSERT(pThis->m_piCallback != NULL);
  284.     
  285.     ulResult = pThis->MainExecution();
  286.     
  287.     return ulResult;
  288. }