ICMP 的 Ping 实现

最近项目需要用到PING功能,在实现时实现了各种版本,但在不同系统平台下总有各种问题,特别WIN8,所有PING值都是0,找了好长时间,问了好多大神都没结果,无意中发现了这种实现方式比较考谱,此中过程说多了都是泪,不多说,直接上源码:



bool Ping(unsigned long ip,int &nDealey,int &bLost)
{
 // Send ping packet
 int nOutTime = GetTickCount();
 int nSend = 0,nRecv = 0,nCountTime = 0;
 for (int i = 0; i < 4; ++ i)
 {
  int a =  GetTickCount();
  HANDLE hICMP;
  /*HANDLE*/HINSTANCE hICMP_DLL;
  DWORD dwRet;
  char acPingBuffer[BUFSIZE] = "\0";
  PIP_ECHO_REPLY pIpe;

  hICMP_DLL = LoadLibrary("ICMP.DLL");
  if (hICMP_DLL == NULL)
  {
   printf("LoadLibrary() failed, unable to locate ICMP.DLL! code: %ld\r\n", GetLastError());
   return FALSE;
  }

  /*
  Get ICMP functions
  */

  lpfnIcmpCreateFile  = (pfnHV)GetProcAddress(hICMP_DLL,"IcmpCreateFile");
  lpfnIcmpCloseHandle = (pfnBH)GetProcAddress(hICMP_DLL,"IcmpCloseHandle");
  lpfnIcmpSendEcho    = (pfnDHDPWPipPDD)GetProcAddress(hICMP_DLL,"IcmpSendEcho");

  if ((!lpfnIcmpCreateFile) ||
   (!lpfnIcmpCloseHandle) ||
   (!lpfnIcmpSendEcho)) {
    printf ("GetProcAddr() failed for at least one function.\n");
    FreeLibrary(hICMP_DLL);
    return FALSE;
  }


  hICMP = (HANDLE)lpfnIcmpCreateFile();
  if (hICMP == INVALID_HANDLE_VALUE)
  {
   printf("IcmpCreateFile() failed. code: %ld\r\n", GetLastError());
   FreeLibrary(hICMP_DLL);
   return FALSE;
  }

  memset(acPingBuffer, 0xAA, sizeof(acPingBuffer));
  pIpe = (PIP_ECHO_REPLY)GlobalAlloc(
   GMEM_FIXED|GMEM_ZEROINIT,
   sizeof(IP_ECHO_REPLY)+sizeof(acPingBuffer));
  if (pIpe == NULL)
  {
   printf("Failed to allocate global ping packet buffer.\r\n");
   lpfnIcmpCloseHandle(hICMP);
   FreeLibrary(hICMP_DLL);
   return FALSE;
  }

  pIpe->Data = acPingBuffer;
  pIpe->DataSize = sizeof(acPingBuffer);


  if ((GetTickCount() - nOutTime) >= 1500)
  {
   break;
  }
  int nTime = GetTickCount();
  ++ nSend;

  IP_OPTION_INFORMATION pInfo;
  pInfo.Ttl = 128;
  pInfo.Tos = 0;
  pInfo.Flags = 0x02/*IP_FLAG_REVERSE*/;
  pInfo.OptionsSize = 0;
  pInfo.OptionsData = NULL;

  dwRet = lpfnIcmpSendEcho(hICMP,
   ip,
   acPingBuffer,
   sizeof(acPingBuffer),
   &pInfo/*NULL*/,
   pIpe,
   sizeof(IP_ECHO_REPLY)+sizeof(acPingBuffer),
   TIMEOUT
   );

  if (dwRet == 0)
  {
   //return FALSE;
   int ntm = GetTickCount() - nTime;
  }
  else
  {
   ++ nRecv;
   nTime = GetTickCount() - nTime;
   nCountTime += nTime;

  }
  GlobalFree(pIpe);
  lpfnIcmpCloseHandle(hICMP);
  FreeLibrary(hICMP_DLL);
  Sleep(100);
 }

 if (0 == nRecv)
 {
  nDealey = 10000;
  bLost = 100;
 }
 else
 {
  nDealey = nCountTime / nRecv;
  double bL = (1 - (double)nRecv / (double)nSend) * 100;
  bLost = bL;
 }

 return TRUE;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值