CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
花落谁家,你作主! 盛大widget设计大赛英雄榜
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C++ Builder >  网络及通讯开发

检测网络速度

楼主netyangsu(一般般)2001-08-01 14:46:09 在 C++ Builder / 网络及通讯开发 提问

各位知道如何检测网速吗?  
  我可不想ping啊。(顺便问一下,要ping的话,程序怎么写?) 问题点数:20、回复次数:9Top

1 楼glcs(古老传说)回复于 2001-08-01 14:56:02 得分 2

MSDN有Ping的VC例子  
  Top

2 楼NowCan(城市浪人)回复于 2001-08-01 17:26:16 得分 14

不用ping的话我不知道,用ping的话请看。  
   
  //These   defines   &   structure   definitions   are   taken   from   the   "ipexport.h"   and  
  //"icmpapi.h"   header   files   as   provided   with   the   Platform   SDK   and  
  //are   used   internally   by   the   CPing   class.   Including   them   here   allows  
  //you   to   compile   the   CPing   code   without   the   need   to   have   the   full  
  //Platform   SDK   installed.  
   
  #ifndef   __PING_H__  
  #define   __PING_H__  
  #define   max(a,   b)     (((a)   >   (b))   ?   (a)   :   (b))  
   
  typedef   unsigned   long   IPAddr;           //   An   IP   address.  
   
  typedef   struct   tagIP_OPTION_INFORMATION  
  {  
      unsigned   char             Ttl;                             //   Time   To   Live  
      unsigned   char             Tos;                             //   Type   Of   Service  
      unsigned   char             Flags;                         //   IP   header   flags  
      unsigned   char             OptionsSize;             //   Size   in   bytes   of   options   data  
      unsigned   char   FAR   *OptionsData;             //   Pointer   to   options   data  
  }   IP_OPTION_INFORMATION;  
   
  typedef   struct   tagICMP_ECHO_REPLY  
  {  
      IPAddr                                 Address;               //   Replying   address  
      unsigned   long                   Status;                 //   Reply   IP_STATUS  
      unsigned   long                   RoundTripTime;   //   RTT   in   milliseconds  
      unsigned   short                 DataSize;             //   Reply   data   size   in   bytes  
      unsigned   short                 Reserved;             //   Reserved   for   system   use  
      void   FAR                             *Data;                   //   Pointer   to   the   reply   data  
      IP_OPTION_INFORMATION   Options;               //   Reply   options  
  }   ICMP_ECHO_REPLY;  
   
  typedef   IP_OPTION_INFORMATION   FAR*   LPIP_OPTION_INFORMATION;  
  typedef   ICMP_ECHO_REPLY   FAR*   LPICMP_ECHO_REPLY;  
  typedef   HANDLE   (WINAPI   IcmpCreateFile)(VOID);  
  typedef   IcmpCreateFile*   lpIcmpCreateFile;  
  typedef   BOOL   (WINAPI   IcmpCloseHandle)(HANDLE   IcmpHandle);  
  typedef   IcmpCloseHandle*   lpIcmpCloseHandle;  
  typedef   DWORD   (WINAPI   IcmpSendEcho)(HANDLE   IcmpHandle,   IPAddr   DestinationAddress,  
                                                                          LPVOID   RequestData,   WORD   RequestSize,  
                                                                          LPIP_OPTION_INFORMATION   RequestOptions,  
                                                                          LPVOID   ReplyBuffer,   DWORD   ReplySize,   DWORD   Timeout);  
  typedef   IcmpSendEcho*   lpIcmpSendEcho;  
   
  ///////////////////////////   Classes   /////////////////////////////////  
   
   
  struct   CPingReply  
  {  
  in_addr   Address;     //The   IP   address   of   the   replier  
  unsigned   long   RTT;   //Round   Trip   time   in   Milliseconds  
  };  
   
  class   CPing  
  {  
  public:  
  //Methods  
      BOOL   Ping(LPCTSTR   pszHostName,   CPingReply&   pr,   UCHAR   nTTL   =   10,   DWORD   dwTimeout   =   5000,   UCHAR   nPacketSize   =   32)   const;  
   
  protected:  
      BOOL   Initialise()   const;  
      static   BOOL   sm_bAttemptedIcmpInitialise;  
      static   lpIcmpCreateFile   sm_pIcmpCreateFile;  
      static   lpIcmpSendEcho   sm_pIcmpSendEcho;  
      static   lpIcmpCloseHandle   sm_pIcmpCloseHandle;  
      static   BOOL   IsSocketReadible(SOCKET   socket,   DWORD   dwTimeout,   BOOL&   bReadible);  
      static   __int64   sm_TimerFrequency;  
  };  
   
   
   
  #endif   //__PING_H__  
   
   
   
  #include   <winsock.h>  
  #include   <stdio.h>  
  #include   "ping.h"  
  #pragma   hdrstop  
   
  //---------------------------------------------------------------------------  
  #pragma   package(smart_init)  
   
  #define   MIN_ICMP_PACKET_SIZE   8         //minimum   8   byte   icmp   packet   (just   header)  
  #define   MAX_ICMP_PACKET_SIZE   1024   //Maximum   icmp   packet   size  
   
  //   IP   header  
  typedef   struct   tagIP_HEADER  
  {  
  unsigned   int   h_len:4;                     //   length   of   the   header  
  unsigned   int   version:4;                 //   Version   of   IP  
  unsigned   char   tos;                           //   Type   of   service  
  unsigned   short   total_len;             //   total   length   of   the   packet  
  unsigned   short   ident;                     //   unique   identifier  
  unsigned   short   frag_and_flags;   //   flags  
  unsigned   char   ttl;  
  unsigned   char   proto;                       //   protocol   (TCP,   UDP   etc)  
  unsigned   short   checksum;               //   IP   checksum  
  unsigned   int   sourceIP;  
  unsigned   int   destIP;  
  }   IP_HEADER;  
  typedef   IP_HEADER   FAR*   LPIP_HEADER;  
   
  //   ICMP   header  
  typedef   struct   tagICMP_HEADER  
  {  
  BYTE   i_type;  
  BYTE   i_code;   /*   type   sub   code   */  
  USHORT   i_cksum;  
  USHORT   i_id;  
  USHORT   i_seq;  
  /*   This   is   not   the   std   header,   but   we   reserve   space   for   time   */  
  ULONG   timestamp;  
  }   ICMP_HEADER;  
  typedef   ICMP_HEADER   FAR*   LPICMP_HEADER;  
   
  void   FillIcmpData(LPICMP_HEADER   pIcmp,   int   nData);  
  BOOL   DecodeResponse(char*   pBuf,   int   nBytes,   sockaddr_in*   from);  
  USHORT   GenerateIPChecksum(USHORT*   pBuffer,   int   nSize);  
   
   
  /////////////////////////////////     Macros   &   Statics   ///////////////////////////  
   
  #ifdef   _DEBUG  
  //#define   new   DEBUG_NEW  
  #undef   THIS_FILE  
  static   char   THIS_FILE[]   =   __FILE__;  
  #endif  
   
  BOOL   CPing::sm_bAttemptedIcmpInitialise   =   FALSE;  
  lpIcmpCreateFile   CPing::sm_pIcmpCreateFile   =   NULL;  
  lpIcmpSendEcho   CPing::sm_pIcmpSendEcho   =   NULL;  
  lpIcmpCloseHandle   CPing::sm_pIcmpCloseHandle   =   NULL;  
   
  __int64   CPing::sm_TimerFrequency   =   0;  
   
   
  //Internal   class   which   is   used   to   ensure   that   the   ICMP  
  //handle   and   winsock   stack   is   closed   upon   exit  
  class   _CPING  
  {  
  public:  
      _CPING();  
  ~_CPING();  
  protected:  
      HINSTANCE   sm_hIcmp;  
   
  friend   class   CPing;  
  };  
   
  _CPING::_CPING()  
  {  
  sm_hIcmp   =   NULL;  
  }  
   
  _CPING::~_CPING()  
  {  
  if   (sm_hIcmp)   {  
    FreeLibrary(sm_hIcmp);  
    sm_hIcmp   =   NULL;  
  }  
  WSACleanup();  
  }  
   
  static   _CPING   _cpingData;  
   
   
   
   
  /////////////////////////////////   Implementation   //////////////////////////////  
   
   
  BOOL   CPing::Initialise()   const  
  {  
  if   (!sm_bAttemptedIcmpInitialise)   {  
  sm_bAttemptedIcmpInitialise   =   TRUE;  
   
  //Initialise   the   winsock   stack  
  WSADATA   wsa;  
  if   (WSAStartup(MAKEWORD(1,   1),   &wsa)   !=   0)   {  
  ::MessageBox(NULL,"WinSock版本不匹配","ERROR",MB_OK);  
  return   FALSE;  
  }  
   
  //Load   up   the   ICMP   library  
  _cpingData.sm_hIcmp   =   LoadLibrary("ICMP.DLL");  
  if   (_cpingData.sm_hIcmp   ==   NULL)   {  
  ::MessageBox(NULL,"无法载入'ICMP.DLL'","ERROR",MB_OK);  
  return   FALSE;  
  }  
   
  //Retrieve   pointers   to   the   functions   in   the   ICMP   dll  
  sm_pIcmpCreateFile   =   (lpIcmpCreateFile)   GetProcAddress(_cpingData.sm_hIcmp,"IcmpCreateFile");  
  sm_pIcmpSendEcho   =   (lpIcmpSendEcho)   GetProcAddress(_cpingData.sm_hIcmp,"IcmpSendEcho"   );  
  sm_pIcmpCloseHandle   =   (lpIcmpCloseHandle)   GetProcAddress(_cpingData.sm_hIcmp,"IcmpCloseHandle");  
  if   (sm_pIcmpCreateFile   ==   NULL   ||   sm_pIcmpSendEcho   ==   NULL   ||  
  sm_pIcmpCloseHandle   ==   NULL)  
  ::MessageBox(NULL,"'ICMP.DLL'中函数无效","ERROR",MB_OK);  
  }  
   
  return   (sm_pIcmpCreateFile   !=   NULL   &&   sm_pIcmpSendEcho   !=   NULL   &&  
                                  sm_pIcmpCloseHandle   !=   NULL);  
  }  
   
   
  BOOL   CPing::IsSocketReadible(SOCKET   socket,   DWORD   dwTimeout,   BOOL&   bReadible)  
  {  
  timeval   timeout   =   {dwTimeout/1000,   dwTimeout   %   1000};  
  fd_set   fds;  
  FD_ZERO(&fds);  
  FD_SET(socket,   &fds);  
  int   nStatus   =   select(0,   &fds,   NULL,   NULL,   &timeout);  
  if   (nStatus   ==   SOCKET_ERROR)   {  
  return   FALSE;  
  }  
  else   {  
  bReadible   =   !(nStatus   ==   0);  
  return   TRUE;  
  }  
  }  
   
  BOOL   CPing::Ping(LPCTSTR   pszHostName,   CPingReply&   pr,   UCHAR   nTTL,   DWORD   dwTimeout,   UCHAR   nPacketSize)   const  
  {  
  //Make   sure   everything   is   initialised  
  if   (!Initialise())  
      return   FALSE;  
   
  LPSTR   lpszAscii   =   (LPTSTR)   pszHostName;  
  //Convert   from   dotted   notation   if   required  
  unsigned   long addr   =   inet_addr(lpszAscii);  
  if   (addr   ==   INADDR_NONE)   {  
  //Not   a   dotted   address,   then   do   a   lookup   of   the   name  
  hostent*   hp   =   gethostbyname(lpszAscii);  
  if   (hp)  
  memcpy(&addr,   hp->h_addr,   hp->h_length);  
  else   {  
              char   msg[64];  
              sprintf(msg,"无法解析主机名:%s",pszHostName);  
  ::MessageBox(NULL,msg,"ERROR",MB_OK);  
  return   FALSE;  
  }  
  }  
   
  //Create   the   ICMP   handle  
  HANDLE   hIP   =   sm_pIcmpCreateFile();  
  if   (hIP   ==   INVALID_HANDLE_VALUE)   {  
  ::MessageBox(NULL,"无效的'ICMP'句柄","ERROR",MB_OK);  
  return   FALSE;  
  }  
   
  //Set   up   the   option   info   structure  
  IP_OPTION_INFORMATION   OptionInfo;  
  ZeroMemory(&OptionInfo,   sizeof(IP_OPTION_INFORMATION));  
  OptionInfo.Ttl   =   nTTL;  
   
  //Set   up   the   data   which   will   be   sent  
  unsigned   char*   pBuf   =   new   unsigned   char[nPacketSize];  
  memset(pBuf,   'E',   nPacketSize);  
   
  //Do   the   actual   Ping  
  int   nReplySize   =   sizeof(ICMP_ECHO_REPLY)   +   max(MIN_ICMP_PACKET_SIZE,   nPacketSize);  
  unsigned   char*   pReply   =   new   unsigned   char[nReplySize];  
  ICMP_ECHO_REPLY*   pEchoReply   =   (ICMP_ECHO_REPLY*)   pReply;  
  DWORD   nRecvPackets   =   sm_pIcmpSendEcho(hIP,   addr,   pBuf,   nPacketSize,   &OptionInfo,   pReply,   nReplySize,   dwTimeout);  
   
  //Check   we   got   the   packet   back  
  BOOL   bSuccess   =   (nRecvPackets   ==   1);  
   
  //Check   the   IP   status   is   OK   (O   is   IP   Success)  
  if   (bSuccess   &&   (pEchoReply->Status   !=   0))   {  
  bSuccess   =   FALSE;  
  SetLastError(pEchoReply->Status);  
  }  
   
  //Check   we   got   the   same   amount   of   data   back   as   we   sent  
  if   (bSuccess)   {  
  bSuccess   =   (pEchoReply->DataSize   ==   nPacketSize);  
  if   (!bSuccess)  
  SetLastError(ERROR_UNEXP_NET_ERR);  
  }  
   
  //Check   the   data   we   got   back   is   what   was   sent  
  if   (bSuccess)   {  
  char*   pReplyData   =   (char*)   pEchoReply->Data;  
  for   (int   i=0;   i<nPacketSize   &&   bSuccess;   i++)  
  bSuccess   =   (pReplyData[i]   ==   'E');  
   
  if   (!bSuccess)  
  SetLastError(ERROR_UNEXP_NET_ERR);  
  }  
   
  //Close   the   ICMP   handle  
  sm_pIcmpCloseHandle(hIP);  
   
  if   (bSuccess)   {  
  //Ping   was   successful,   copy   over   the   pertinent   info  
  //into   the   return   structure  
  pr.Address.S_un.S_addr   =   pEchoReply->Address;  
  pr.RTT   =   pEchoReply->RoundTripTime;  
  }  
   
  //Free   up   the   memory   we   allocated  
  delete   []   pBuf;  
  delete   []   pReply;  
   
  //return   the   status  
  return   bSuccess;  
  }  
   
   
   
  Top

3 楼wangxd(东东)回复于 2001-08-01 17:49:06 得分 2

win2000下有函数可以直接获得的,记不请了,98下不知道  
  你问问“大富翁”的“温柔一刀”把Top

4 楼netyangsu(一般般)回复于 2001-08-01 22:23:14 得分 0

高手请过来,help!  
  上面的东东是有道理,要给分,但是对本菜鸟也太累了一点,请问有没有简便一点的办法实现ping啊?不用ping测网速也行啊!  
   
  Top

5 楼XioGua(明日复明日)回复于 2001-08-01 22:30:03 得分 2

用Delphi6.0,  
   
  我记得大概在Indy页面的Icmp控件就有这个功能。。。  
   
  0_0Top

6 楼netyangsu(一般般)回复于 2001-08-02 20:31:28 得分 0

Delphi6.0俺不会啊,我是菜鸟啊,难道BCB就不行吗???Top

7 楼gqxs(我心㊣飞翔)回复于 2001-08-02 20:51:41 得分 0

upTop

8 楼netyangsu(一般般)回复于 2001-08-04 16:06:20 得分 0

冲啊!!!Top

9 楼netyangsu(一般般)回复于 2001-08-04 22:30:12 得分 0

请教简便一点的办法Top

相关问题

  • 能否提供一个检测网络速度的软件?
  • 怎样检测网络连接速度?(如果分不够可以再加)
  • 如何检测网线的速度
  • 网络检测问题!
  • 如何检测用户机子的运行速度?(内详)
  • 讨论:如何检测网络状态??
  • 网络速度问题
  • 获得网络速度
  • 请教:如可检测网络的突然中断?
  • 如何检测网络连接是否正常?

关键词

  • cping
  • sm
  • hicmp
  • cpingdata
  • icmp
  • battemptedicmpinitialise
  • lpicmpcreatefile
  • lpicmpclosehandle
  • lpicmpsendecho
  • picmpclosehandle

得分解答快速导航

  • 帖主:netyangsu
  • glcs
  • NowCan
  • wangxd
  • XioGua

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo