Poco::Net::ICMPClient を紹介します。
ICMPClientTest.cpp
・Poco::Net::ICMPClient の static method
static int ping(SocketAddress& address, IPAddress::Family family, int repeat = 1);
static int pingIPv4(const std::string& address, int repeat = 1);
を呼んで、結果(ping の回数分の戻り値が来たかどうか)を表示。
・Poco::Net::ICMPClient をインスタンス化し、non-static の method
int ping(const std::string& address, int repeat = 1) const;
を呼んで、結果を表示。
さらに、ICMPClientTest クラスで、pingBegin, pingReply, pingError, pingEnd の Notification イベント
ハンドラを登録しておいて
int ping(SocketAddress& address, int repeat = 1) const;
を呼び、各 Notification の内容と最終結果を表示。
#include <Poco/Format.h> #include <Poco/Net/ICMPClient.h> #include <Poco/Net/IPAddress.h> #include <Poco/Net/ICMPEventArgs.h> #include <Poco/Delegate.h> #include <string> #include "ScopedLogMessage.h" #include "PrepareConsoleLogger.h" const std::string IsOK(bool isOK) { return isOK ? "OK":"NG"; } class ICMPClientTest { public: ICMPClientTest( ScopedLogMessage& msg, Poco::Net::ICMPClient& client) : m_msg (msg) , m_client (client) { m_client.pingBegin += Poco::Delegate<ICMPClientTest, Poco::Net::ICMPEventArgs>(this, &ICMPClientTest::onBegin); m_client.pingReply += Poco::Delegate<ICMPClientTest, Poco::Net::ICMPEventArgs>(this, &ICMPClientTest::onReply); m_client.pingError += Poco::Delegate<ICMPClientTest, Poco::Net::ICMPEventArgs>(this, &ICMPClientTest::onError); m_client.pingEnd += Poco::Delegate<ICMPClientTest, Poco::Net::ICMPEventArgs>(this, &ICMPClientTest::onEnd); } ~ICMPClientTest() { m_client.pingBegin -= Poco::Delegate<ICMPClientTest, Poco::Net::ICMPEventArgs>(this, &ICMPClientTest::onBegin); m_client.pingReply -= Poco::Delegate<ICMPClientTest, Poco::Net::ICMPEventArgs>(this, &ICMPClientTest::onReply); m_client.pingError -= Poco::Delegate<ICMPClientTest, Poco::Net::ICMPEventArgs>(this, &ICMPClientTest::onError); m_client.pingEnd -= Poco::Delegate<ICMPClientTest, Poco::Net::ICMPEventArgs>(this, &ICMPClientTest::onEnd); } int ping(Poco::Net::SocketAddress& address, int repeat) const { return m_client.ping(address, repeat); } void onBegin(const void* pSender, Poco::Net::ICMPEventArgs& args) { m_msg.Message(Poco::format(" Pinging %s [%s] with %d bytes of data:", args.hostName(), args.hostAddress(), args.dataSize())); } void onReply(const void* pSender, Poco::Net::ICMPEventArgs& args) { m_msg.Message(Poco::format(" Reply from %s bytes=%d time=%dms TTL=%d", args.hostName(), args.dataSize(), args.replyTime(), args.ttl())); } void onError(const void* pSender, Poco::Net::ICMPEventArgs& args) { m_msg.Message(Poco::format(" Error: %s ", args.error())); } void onEnd(const void* pSender, Poco::Net::ICMPEventArgs& args) { int received = args.received(); m_msg.Message(Poco::format(" Ping statistics for %s", args.hostName())); m_msg.Message(Poco::format(" Packets: Sent=%d, Received=%d, Lost=%d (%3.3f%% loss)", args.sent(), received, args.repetitions() - received, 100.0 - args.percent())); m_msg.Message(Poco::format(" Approximate round trip times: Minimum=%dms, Maximum=%dms, Average=%dms", args.minRTT(), args.maxRTT(), args.avgRTT())); } private: ScopedLogMessage& m_msg; Poco::Net::ICMPClient& m_client; }; int main(int /*argc*/, char** /*argv*/) { PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION); ScopedLogMessage msg("ICMPClientTest ", "start", "end"); try { const std::string url("poco.roundsquare.net"); const std::string urlWithPort(url+":80"); const int numRepeat = 5; Poco::Net::SocketAddress socketAddress(urlWithPort); msg.Message("*** static methods ***"); msg.Message(Poco::format(" Poco::Net::ICMPClient::ping() - %s", IsOK(numRepeat == Poco::Net::ICMPClient::ping(socketAddress, Poco::Net::IPAddress::IPv4, numRepeat)))); msg.Message(Poco::format(" Poco::Net::ICMPClient::pingIPv4() - %s", IsOK(numRepeat == Poco::Net::ICMPClient::pingIPv4(url, numRepeat)))); msg.Message("*** non-static methods ***"); Poco::Net::ICMPClient icmpClient(Poco::Net::IPAddress::IPv4); msg.Message(Poco::format(" Poco::Net::ICMPClient::ping(const std::string& address, int repeat) - %s", IsOK(numRepeat == icmpClient.ping(url, numRepeat)))); ICMPClientTest test(msg, icmpClient); msg.Message(" ICMPClientTest::ping() start"); msg.Message(Poco::format(" ICMPClientTest::ping() - %s", IsOK(numRepeat == test.ping(socketAddress, numRepeat)))); } catch(Poco::IOException&) { msg.Message(" CAUTION: You need to sudo to run this app."); } return 0; } |
Results of execution
・Linux と Mac で実行する時は、sudo してからでないと exception が飛んでしまうので注意。
(socket() を SOCK_RAW で呼ぶ時には root 特権か CAP_NET_RAW 権限が必要なため)
・On Linux
$ sudo ./ICMPClientTest [0] ICMPClientTest start [0] *** static methods *** [0] Poco::Net::ICMPClient::ping() - OK [0] Poco::Net::ICMPClient::pingIPv4() - OK [0] *** non-static methods *** [0] Poco::Net::ICMPClient::ping(const std::string& address, int repeat) - OK [0] ICMPClientTest::ping() start [0] Pinging poco.roundsquare.net [210.198.10.133] with 48 bytes of data: [0] Reply from poco.roundsquare.net bytes=48 time=31ms TTL=128 [0] Reply from poco.roundsquare.net bytes=48 time=31ms TTL=128 [0] Reply from poco.roundsquare.net bytes=48 time=32ms TTL=128 [0] Reply from poco.roundsquare.net bytes=48 time=31ms TTL=128 [0] Reply from poco.roundsquare.net bytes=48 time=31ms TTL=128 [0] Ping statistics for poco.roundsquare.net [0] Packets: Sent=5, Received=5, Lost=0 (0.000% loss) [0] Approximate round trip times: Minimum=31ms, Maximum=32ms, Average=31ms [0] ICMPClientTest::ping() - OK [0] ICMPClientTest end |
・On Macintosh OSX 10.6.6
$ sudo ./ICMPClientTest [0] ICMPClientTest start [0] *** static methods *** [0] Poco::Net::ICMPClient::ping() - OK [0] Poco::Net::ICMPClient::pingIPv4() - OK [0] *** non-static methods *** [0] Poco::Net::ICMPClient::ping(const std::string& address, int repeat) - OK [0] ICMPClientTest::ping() start [0] Pinging mail.roundsquare.net [210.198.10.133] with 48 bytes of data: [0] Reply from mail.roundsquare.net bytes=48 time=31ms TTL=128 [0] Reply from mail.roundsquare.net bytes=48 time=31ms TTL=128 [0] Reply from mail.roundsquare.net bytes=48 time=31ms TTL=128 [0] Reply from mail.roundsquare.net bytes=48 time=30ms TTL=128 [0] Reply from mail.roundsquare.net bytes=48 time=31ms TTL=128 [0] Ping statistics for mail.roundsquare.net [0] Packets: Sent=5, Received=5, Lost=0 (0.000% loss) [0] Approximate round trip times: Minimum=30ms, Maximum=31ms, Average=30ms [0] ICMPClientTest::ping() - OK [0] ICMPClientTest end |
・On Windows XP sp3
[0] ICMPClientTest start [0] *** static methods *** [0] Poco::Net::ICMPClient::ping() - OK [0] Poco::Net::ICMPClient::pingIPv4() - OK [0] *** non-static methods *** [0] Poco::Net::ICMPClient::ping(const std::string& address, int repeat) - OK [0] ICMPClientTest::ping() start [0] Pinging poco.roundsquare.net [210.198.10.133] with 48 bytes of data: [0] Reply from poco.roundsquare.net bytes=48 time=31ms TTL=128 [0] Reply from poco.roundsquare.net bytes=48 time=31ms TTL=128 [0] Reply from poco.roundsquare.net bytes=48 time=46ms TTL=128 [0] Reply from poco.roundsquare.net bytes=48 time=31ms TTL=128 [0] Reply from poco.roundsquare.net bytes=48 time=31ms TTL=128 [0] Ping statistics for poco.roundsquare.net [0] Packets: Sent=5, Received=5, Lost=0 (0.000% loss) [0] Approximate round trip times: Minimum=31ms, Maximum=46ms, Average=34ms [0] ICMPClientTest::ping() - OK [0] ICMPClientTest end |
Downloads
・ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2011年3月20日からのダウンロード数:1250
Subversion
・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。
![]() |
Copyright © 2011 Round Square Inc. All rights reserved. |
---|
0 Comments.