ACE下的PING功能实现
本帖最后由 freeeyes 于 2011-10-26 17:32 编辑虽说ping被很多服务器的防火墙默认拒绝,不过,做一个简单的ping命令有时候还是有所必要的。用ACE实现一个ping非常简单,不超过40行代码即可实现。查了一下网上的ACE的ping代码,似乎都多少有点问题。这里放一个可以运行的。供大家参考抛砖。
首先,需要引用一个ACE_Ping_Socket,它继承来自ACE_ICMP_Socket。ping需要远端提供ICMP支持。
代码如下:
#include "ace/OS_main.h"
#include "ace/INET_Addr.h"
#include "ace/Log_Msg.h"
#include "ace/Time_Value.h"
#include "ace/OS_NS_sys_time.h"
#include "ace/OS_NS_unistd.h"
#include "ace/Ping_Socket.h"
class CPing
{
public:
CPing(void);
~CPing(void);
bool PingHost(const char* pServerIP, int nTimeout, int& nTimeCost);
private:
ACE_Ping_Socket m_Ping;
};
这里提供一个方法。PingHost()
pServerIP是你要ping的远程服务器地址。
nTimeout是的ping命令超时的时间。(不能无限制等下去)
nTimeCost返回一个时间消耗,单位是毫秒。
其实对于ping,我们知道是否能ping通,时间消耗多少,往往就够了。
好了。来看看实现代码。
#include "Ping.h"
CPing::CPing(void)
{
}
CPing::~CPing(void)
{
}
bool CPing::PingHost(const char* pServerIP, int nTimeout, int& nTimeCost)
{
//发送的测试数据
ACE_INET_Addr addrRemote;
int nErr = addrRemote.set("0", pServerIP);
if(nErr != 0)
{
ACE_DEBUG((LM_ERROR, "set_address error[%d].\n", errno));
return false;
}
nErr = m_Ping.open(ACE_INET_Addr::sap_any);
if(nErr != 0)
{
ACE_DEBUG((LM_ERROR, "open error[%d].\n", errno));
return false;
}
ACE_Time_Value tvTimeBegin;
ACE_Time_Value tvTimeEnd;
ACE_Time_Value tvRecvCost;
ACE_Time_Value tvTimeout(nTimeout, 0);
tvTimeBegin = ACE_OS::gettimeofday();
int nmcData = m_Ping.make_echo_check(addrRemote, false, &tvTimeout);
if(nmcData != 0)
{
ACE_DEBUG((LM_ERROR, "make_echo_check error[%d].\n", errno));
m_Ping.close();
return false;
}
tvTimeEnd = ACE_OS::gettimeofday();
tvRecvCost = tvTimeEnd - tvTimeBegin;
nTimeCost = (int)tvRecvCost.msec();
m_Ping.close();
return true;
}
这里解释一下,谷歌了一下一些关于用这个类的问题,很多人不知道为什么ping会返回-1.
其实解决这类问题的关键点是
m_Ping.open(ACE_INET_Addr::sap_any);
好了,以上代码并不难理解。
自己测试一下上述代码吧。
int main(int argc, char* argv[])
{
int nTimeCost = 0;
CPing objPing;
for(int i = 0; i < 5; i++)
{
char* pIP = {"123.103.14.237"};
if(true == objPing.PingHost(pIP, 2, nTimeCost))
{
ACE_DEBUG((LM_INFO, "IP=[%s] TimeCost=[%d].\n", pIP, nTimeCost));
}
ACE_Time_Value tvSleep(1, 0);
ACE_OS::sleep(tvSleep);
}
getchar();
return 0;
}
呵呵,123.103.14.237是网易的IP,你可以实际ping一下,对比一下两个数值。
这里多一句嘴,在ACE的ping类里面提供两个函数,一个是我上述用到的make_echo_check(),这个协议是发送一个ICMP数据包来回(一个send,一个recv)后的时间,另外还有一个接口是send_echo_check(),这个方法是只发送一个ICMP,并不接收回应,只要发送成功即返回,可以用于查看某一个IP是否有效,而不在乎响应时间的应用。你可以在这段代码中稍微改一下就可以了。
好了,呵呵,以上代码在我的VS2005 + ACE6.0 + WinXP下测试通过。最近项目比较忙,呵呵,这两天把0.82上传上来,增加了一些给力的功能。 期待给力的新功能:lol
页:
[1]