Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16500801
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:07:31

下载本文示例代码
          推荐:经典教程专区  极其常用的Ping命令通过向计算机发送ICMP Echo请求报文并且监听回应报文的返回,以校验与远程计算机或本地计算机的连接。  使用ICMP.DLL实现Ping  在Windows平台编程中实现Ping的一个最简单方法是调用ICMP.DLL这个动态链接库,引用ICMP.DLL中的三个函数即可: HANDLE IcmpCreateFile(void);   这个函数打开个ICMP Echo请求能使用的句柄; BOOL IcmpCloseHandle(HANDLE IcmpHandle);  这个函数关闭由IcmpCreateFile打开的句柄; DWORD IcmpSendEcho( HANDLE IcmpHandle, // IcmpCreateFile打开的句柄 IPAddr DestinationAddress, //Echo请求的目的地址  LPVOID RequestData, //发送数据buffer WORD RequestSize, //发送数据长度 PIP_OPTION_INFORMATION RequestOptions, // IP_OPTION_INFORMATION指针 LPVOID ReplyBuffer, //接收回复buffer DWORD ReplySize, //接收回复buffer大小 DWORD Timeout //等待超时);  这个函数发送Echo请求并等待回复或超时。  把这个函数和相关数据封装成一个类CPing,CPing类的头文件如下: class CPing{ public:  CPing();  ~CPing();  BOOL Ping(char* strHost);  private:  // ICMP.DLL 导出函数指针  HANDLE (WINAPI *pIcmpCreateFile)(VOID);  BOOL (WINAPI *pIcmpCloseHandle)(HANDLE);  DWORD (WINAPI *pIcmpSendEcho)(HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD);  HANDLE hndlIcmp; // 加载ICMP.DLL库句柄  BOOL bValid; //是否构造(获得ICMP.DLL导出函数指针和初始化WinSock)成功};  CPing类的构造函数获得ICMP.DLL中导出函数的指针并初始化WinSock: CPing::CPing(){ bValid = FALSE; WSADATA wsaData; int nRet;  // 动态加载ICMP.DLL hndlIcmp = LoadLibrary("ICMP.DLL"); if (hndlIcmp == NULL) {  ::MessageBox(NULL, "Could not load ICMP.DLL", "Error:", MB_OK);  return; } // 获得ICMP.DLL中导出函数指针 pIcmpCreateFile = (HANDLE (WINAPI *)(void))GetProcAddress((HMODULE)hndlIcmp,"IcmpCreateFile"); pIcmpCloseHandle = (BOOL (WINAPI *)(HANDLE))GetProcAddress((HMODULE)hndlIcmp,"IcmpCloseHandle"); pIcmpSendEcho = (DWORD (WINAPI *)(HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD))GetProcAddress((HMODULE)hndlIcmp,"IcmpSendEcho"); // 检查所有的指针 if (pIcmpCreateFile == NULL || pIcmpCloseHandle == NULL ||pIcmpSendEcho == NULL) {  ::MessageBox(NULL, "Error loading ICMP.DLL", "Error:", MB_OK);  FreeLibrary((HMODULE)hndlIcmp);  return; } // 初始化WinSock nRet = WSAStartup(0x0101, &wsaData ); if (nRet) {  ::MessageBox(NULL, "WSAStartup() error:", "Error:", MB_OK);  WSACleanup();  FreeLibrary((HMODULE)hndlIcmp);  return; } // 检查WinSock的版本 if (0x0101 != wsaData.wVersion) {  ::MessageBox(NULL, "No WinSock version 1.1 support found", "Error:", MB_OK);  WSACleanup();  FreeLibrary((HMODULE)hndlIcmp);  return; } bValid = TRUE;}  CPing类的析构函数完成相反的动作: CPing::~CPing(){ WSACleanup(); FreeLibrary((HMODULE)hndlIcmp);}  CPing类的Ping函数是最核心的函数,实现真正的ping操作: int CPing::Ping(char *strHost){ struct in_addr iaDest; // Internet地址结构体 LPHOSTENT pHost; // 主机入口结构体指针 DWORD *dwAddress; // IP地址 IPINFO ipInfo; // IP选项结构体 ICMPECHO icmpEcho; // ICMP Echo回复buffer HANDLE hndlFile; // IcmpCreateFile函数打开的句柄 if (!bValid) {  return FALSE; } //使用inet_addr()以判定ping目标为地址还是名称 iaDest.s_addr = inet_addr(strHost); if (iaDest.s_addr == INADDR_NONE)  pHost = gethostbyname(strHost); else  pHost = gethostbyaddr((const char*) &iaDest, sizeof(struct in_addr),AF_INET);  if (pHost == NULL)  {   return FALSE;  }  // 拷贝IP地址  dwAddress = (DWORD*)(*pHost->h_addr_list);  // 获得ICMP Echo句柄  hndlFile = pIcmpCreateFile();  // 设置发送信息缺省值  ipInfo.Ttl = 255;  ipInfo.Tos = 0;  ipInfo.IPFlags = 0;  ipInfo.OptSize = 0;  ipInfo.Options = NULL;  icmpEcho.Status = 0;  // 请求一个ICMP echo  pIcmpSendEcho(hndlFile, *dwAddress, NULL, 0, &ipInfo, &icmpEcho, sizeof(struct tagICMPECHO), 1000);  //设置结果  iaDest.s_addr = icmpEcho.Source;  if (icmpEcho.Status)  {   return FALSE;  }  // 关闭ICMP Echo句柄  pIcmpCloseHandle(hndlFile);  return TRUE;}  其中所使用的相关结构体定义为: typedef struct tagIPINFO{ u_char Ttl; // TTL u_char Tos; // 服务类型 u_char IPFlags; // IP标志 u_char OptSize; // 可选数据大小 u_char *Options; // 可选数据buffer} IPINFO, *PIPINFO;typedef struct tagICMPECHO{ u_long Source; // 源地址 u_long Status; // IP状态 u_long RTTime; // RTT u_short DataSize; // 回复数据大小 u_short Reserved; // 保留 void *pData; // 回复数据buffer IPINFO ipInfo; // 回复IP选项} ICMPECHO, *PICMPECHO;共3页。 1 2 3 :           推荐:经典教程专区  极其常用的Ping命令通过向计算机发送ICMP Echo请求报文并且监听回应报文的返回,以校验与远程计算机或本地计算机的连接。  使用ICMP.DLL实现Ping  在Windows平台编程中实现Ping的一个最简单方法是调用ICMP.DLL这个动态链接库,引用ICMP.DLL中的三个函数即可: HANDLE IcmpCreateFile(void);   这个函数打开个ICMP Echo请求能使用的句柄; BOOL IcmpCloseHandle(HANDLE IcmpHandle);  这个函数关闭由IcmpCreateFile打开的句柄; DWORD IcmpSendEcho( HANDLE IcmpHandle, // IcmpCreateFile打开的句柄 IPAddr DestinationAddress, //Echo请求的目的地址  LPVOID RequestData, //发送数据buffer WORD RequestSize, //发送数据长度 PIP_OPTION_INFORMATION RequestOptions, // IP_OPTION_INFORMATION指针 LPVOID ReplyBuffer, //接收回复buffer DWORD ReplySize, //接收回复buffer大小 DWORD Timeout //等待超时);  这个函数发送Echo请求并等待回复或超时。  把这个函数和相关数据封装成一个类CPing,CPing类的头文件如下: class CPing{ public:  CPing();  ~CPing();  BOOL Ping(char* strHost);  private:  // ICMP.DLL 导出函数指针  HANDLE (WINAPI *pIcmpCreateFile)(VOID);  BOOL (WINAPI *pIcmpCloseHandle)(HANDLE);  DWORD (WINAPI *pIcmpSendEcho)(HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD);  HANDLE hndlIcmp; // 加载ICMP.DLL库句柄  BOOL bValid; //是否构造(获得ICMP.DLL导出函数指针和初始化WinSock)成功};  CPing类的构造函数获得ICMP.DLL中导出函数的指针并初始化WinSock: CPing::CPing(){ bValid = FALSE; WSADATA wsaData; int nRet;  // 动态加载ICMP.DLL hndlIcmp = LoadLibrary("ICMP.DLL"); if (hndlIcmp == NULL) {  ::MessageBox(NULL, "Could not load ICMP.DLL", "Error:", MB_OK);  return; } // 获得ICMP.DLL中导出函数指针 pIcmpCreateFile = (HANDLE (WINAPI *)(void))GetProcAddress((HMODULE)hndlIcmp,"IcmpCreateFile"); pIcmpCloseHandle = (BOOL (WINAPI *)(HANDLE))GetProcAddress((HMODULE)hndlIcmp,"IcmpCloseHandle"); pIcmpSendEcho = (DWORD (WINAPI *)(HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD))GetProcAddress((HMODULE)hndlIcmp,"IcmpSendEcho"); // 检查所有的指针 if (pIcmpCreateFile == NULL || pIcmpCloseHandle == NULL ||pIcmpSendEcho == NULL) {  ::MessageBox(NULL, "Error loading ICMP.DLL", "Error:", MB_OK);  FreeLibrary((HMODULE)hndlIcmp);  return; } // 初始化WinSock nRet = WSAStartup(0x0101, &wsaData ); if (nRet) {  ::MessageBox(NULL, "WSAStartup() error:", "Error:", MB_OK);  WSACleanup();  FreeLibrary((HMODULE)hndlIcmp);  return; } // 检查WinSock的版本 if (0x0101 != wsaData.wVersion) {  ::MessageBox(NULL, "No WinSock version 1.1 support found", "Error:", MB_OK);  WSACleanup();  FreeLibrary((HMODULE)hndlIcmp);  return; } bValid = TRUE;}  CPing类的析构函数完成相反的动作: CPing::~CPing(){ WSACleanup(); FreeLibrary((HMODULE)hndlIcmp);}  CPing类的Ping函数是最核心的函数,实现真正的ping操作: int CPing::Ping(char *strHost){ struct in_addr iaDest; // Internet地址结构体 LPHOSTENT pHost; // 主机入口结构体指针 DWORD *dwAddress; // IP地址 IPINFO ipInfo; // IP选项结构体 ICMPECHO icmpEcho; // ICMP Echo回复buffer HANDLE hndlFile; // IcmpCreateFile函数打开的句柄 if (!bValid) {  return FALSE; } //使用inet_addr()以判定ping目标为地址还是名称 iaDest.s_addr = inet_addr(strHost); if (iaDest.s_addr == INADDR_NONE)  pHost = gethostbyname(strHost); else  pHost = gethostbyaddr((const char*) &iaDest, sizeof(struct in_addr),AF_INET);  if (pHost == NULL)  {   return FALSE;  }  // 拷贝IP地址  dwAddress = (DWORD*)(*pHost->h_addr_list);  // 获得ICMP Echo句柄  hndlFile = pIcmpCreateFile();  // 设置发送信息缺省值  ipInfo.Ttl = 255;  ipInfo.Tos = 0;  ipInfo.IPFlags = 0;  ipInfo.OptSize = 0;  ipInfo.Options = NULL;  icmpEcho.Status = 0;  // 请求一个ICMP echo  pIcmpSendEcho(hndlFile, *dwAddress, NULL, 0, &ipInfo, &icmpEcho, sizeof(struct tagICMPECHO), 1000);  //设置结果  iaDest.s_addr = icmpEcho.Source;  if (icmpEcho.Status)  {   return FALSE;  }  // 关闭ICMP Echo句柄  pIcmpCloseHandle(hndlFile);  return TRUE;}  其中所使用的相关结构体定义为: typedef struct tagIPINFO{ u_char Ttl; // TTL u_char Tos; // 服务类型 u_char IPFlags; // IP标志 u_char OptSize; // 可选数据大小 u_char *Options; // 可选数据buffer} IPINFO, *PIPINFO;typedef struct tagICMPECHO{ u_long Source; // 源地址 u_long Status; // IP状态 u_long RTTime; // RTT u_short DataSize; // 回复数据大小 u_short Reserved; // 保留 void *pData; // 回复数据buffer IPINFO ipInfo; // 回复IP选项} ICMPECHO, *PICMPECHO;共3页。 1 2 3 : 下载本文示例代码


原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping原始套接字透析之实现Ping
阅读(232) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~