C++ Builder中如何实现Ping操作?

zhpch 2007-04-10 07:29:36
C++ Builder中如何实现Ping操作?

ping 192.168.0.1

怎样实现这个操作并判断是否ping通

谢谢大家!!!
...全文
1016 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Ronagon 2008-04-19
  • 打赏
  • 举报
回复
这段代码我试了试,为什么只能ping内网呢?
loki2k 2007-04-16
  • 打赏
  • 举报
回复
楼上都是牛人啊
地层的东西都挖出来了,够你爽滴了。。。。
海嵌 2007-04-11
  • 打赏
  • 举报
回复
#include <winsock.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) {
ShowMessage("WinSock版本不匹配\n");
return FALSE;
}

//Load up the ICMP library
_cpingData.sm_hIcmp = LoadLibrary("ICMP.DLL");
if (_cpingData.sm_hIcmp == NULL) {
ShowMessage("无法载入'ICMP.DLL'\n");
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)
ShowMessage("'ICMP.DLL'中函数无效\n");
}

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 {
ShowMessage("无法解析主机名:"+ AnsiString(pszHostName));
return FALSE;
}
}

//Create the ICMP handle
HANDLE hIP = sm_pIcmpCreateFile();
if (hIP == INVALID_HANDLE_VALUE) {
ShowMessage("无效的'ICMP'句柄\n");
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((int)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((int)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;
}
海嵌 2007-04-11
  • 打赏
  • 举报
回复
转:
//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__
我不懂电脑 2007-04-11
  • 打赏
  • 举报
回复
bcb6提供了TIdIcmpClient组件很好用。
huzhangyou 2007-04-10
  • 打赏
  • 举报
回复
http://vip.6to23.com/NowCan1/code/scrsp_s.zip
这里面有一个ping类。
huzhangyou 2007-04-10
  • 打赏
  • 举报
回复
void __fastcall ProbeThread::Execute()
{
//---- Place thread code here ----
TIdIcmpClient *PingClient=new TIdIcmpClient(NULL);
PingClient->OnReply=ParseReply;
PingClient->Port=nPort++;
PingClient->ReceiveTimeout=2000;
PingClient->BufferSize=100;
while(1)
{

Sleep((unsigned int)100);
Form1->pSection->Acquire();
if(nProbeIndex>=Form1->pList->Count)
{
break;
}
PingClient->Host=((AnsiString*)Form1->pList->Items[nProbeIndex])->c_str();
nProbeIndex++;
Form1->pSection->Release();


PingClient->Ping();

Form1->pTemp->Acquire();
Form1->Memo1->Text=Form1->Memo1->Text+"\r\n";
Form1->Memo1->Text=Form1->Memo1->Text+(AnsiString)(PingClient->Host);
Form1->pTemp->Release();
}

delete PingClient;
}
C++Builder 资料库 提供50多个例子,带目录 1.怎样在C++Builder创建使用DLL 2.用C++Bulider在WIN.INI保存信息 3.如何在C++Builder检测硬件 4.C++Builder如何响应消息及自定义消息 5.利用C++ Builder开发动画DLL 6.用C++ Builder 3制作屏幕保护程序 7.TCP/IP头格式 8.UDP 9.判断windows的Desktop及其它目录 10用C++Builder创建数字签名 11用Enter 键控制焦点切换的方法 12.拦 截 Windows 消 息 13.使用CommaText 14.程序开始时先显示信息框 15.怎样获取程序的命令行参数? 16.如何监视剪贴板 17.如何使用OnIdle事件 18.用C++Builder编写串行异步通信程序 19.C++BUILDER非可视组件的消息处理技巧 20.用C++Builder 建立数据库VCL使用经验 21.用C++ Builder创建基于Internet的点对点Chat 22.用C++Builder获取应用程序图标 23.BIG5到GB的转换技术 24.C++BUILDER让你的任务栏图标动起来 25.TFORM 26.用BCB在windows桌面创建快捷方式 27.读磁片磁区 28.I/O 端口读写的实现 29.检测鼠标位置 30.令Win32 应用程序跳入系统零层 31.如何取得Memo的行和列 32.使用Sockets 33.Windows95/98下怎样隐藏应用程序不让它出现在CTRL-ALT-DEL对话框? 34.怎样隐藏应用程序的任务条图标 35.编写自己的Ping.exe程序 36.用C++Builder在WINNT下编制一个Service 37.如何在C++ BUILDER自动关闭WINDOWS屏保 38.显示/隐藏任务栏图标 39.信箱监视程序 40.C++Building制作闹钟 41.拨号上网IP地址的检知 42.用C++ Builder编写Tray程序 43.怎样用代码来最小化或恢复程序 44.制作主窗口显示前的版权窗口 45.判断是否已经联到 internet 46.获取登陆用户名 47.隐藏桌面图标 48.程序启动时运行 49.控制面板的调用 50.模拟键盘按键 51.让标题栏闪烁 52.启动屏幕保护 53.年月日星期的取法 54.键盘事件 55.隐藏任务栏 56.禁止关机 57.怎样以最小化方式启动程序 58.在Memo增加一行后,如何使最后一行能显示 59.设置壁纸方法

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧