|
本帖最后由 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, "[CPing::PingHost]set_address error[%d].\n", errno));
- return false;
- }
- nErr = m_Ping.open(ACE_INET_Addr::sap_any);
- if(nErr != 0)
- {
- ACE_DEBUG((LM_ERROR, "[CPing::PingHost]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, "[CPing::PingHost]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, "[CPing::PingHost]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上传上来,增加了一些给力的功能。 |
|