From: Guilherme Maciel Ferreira Date: Tue, 1 Mar 2011 15:01:57 +0000 (+0100) Subject: Pinger interface now allows to specify the number of pings to perform X-Git-Tag: v1.0~170 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=5c670f6b20da6ec853580ebde5e302a56e16046d;p=pingcheck Pinger interface now allows to specify the number of pings to perform --- diff --git a/src/main.cpp b/src/main.cpp index 8a611b7..7fc2099 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,7 +24,7 @@ int main( int argc, char* argv[] ) Configuration config = config_reader.get_configuration(); Host host = config.get_host(); string destination = host.get_address(); - p.ping( destination ); + p.ping( destination, 50 ); } catch ( std::exception& e ) { diff --git a/src/ping/boostpinger.cpp b/src/ping/boostpinger.cpp index 75b7b92..5e09a67 100644 --- a/src/ping/boostpinger.cpp +++ b/src/ping/boostpinger.cpp @@ -30,7 +30,10 @@ BoostPinger::BoostPinger( SequenceNumber( 0 ), TimeSent( posix_time::microsec_clock::universal_time() ), ReplyBuffer(), - NumReplies( 0 ) + RepliesCount( 0 ), + TimesToPingTotal( 0 ), + MinTimesToPing( 0 ), + MaxTimesToPing( std::numeric_limits::max() ) { } @@ -38,22 +41,53 @@ BoostPinger::~BoostPinger() { } -void BoostPinger::ping( const std::string &destination ) +void BoostPinger::ping( + const std::string &destination, + const std::size_t times_to_ping +) { BOOST_ASSERT( !destination.empty() ); + BOOST_ASSERT( ( MinTimesToPing < times_to_ping ) && ( times_to_ping < MaxTimesToPing ) ); icmp::resolver::query query( icmp::v4(), destination, "" ); DestinationEndpoint = *Resolver.resolve( query ); + TimesToPingTotal = times_to_ping; + + start_pinger(); +} + +void BoostPinger::start_pinger() +{ start_send(); start_receive(); io_service.run(); } +void BoostPinger::stop_pinger() +{ + io_service.stop(); +} + void BoostPinger::start_send() { - IcmpData icmp_data( "ping message" ); + IcmpPacket icmp_echo_request_packet = create_echo_request_packet(); + + std::size_t times_already_pinged = SequenceNumber; + if ( times_already_pinged <= TimesToPingTotal ) + { + send_echo_request( icmp_echo_request_packet ); + } + else + { + stop_pinger(); + } +} + +IcmpPacket BoostPinger::create_echo_request_packet() +{ + IcmpData icmp_data( "ping-message" ); // Create an ICMP header for an echo request. SequenceNumber++; @@ -65,17 +99,7 @@ void BoostPinger::start_send() IcmpHeader icmp_header( type, code, checksum, identifier, SequenceNumber ); // Encode the ICMP header and data in an ICMP packet. - IcmpPacket icmp_echo_request_packet( icmp_header, icmp_data ); - - int ping_times = SequenceNumber; - if ( ping_times < 4 ) - { - send_echo_request( icmp_echo_request_packet ); - } - else - { - io_service.stop(); - } + return IcmpPacket( icmp_header, icmp_data ); } void BoostPinger::send_echo_request( const IcmpPacket &icmp_packet ) @@ -89,14 +113,14 @@ void BoostPinger::send_echo_request( const IcmpPacket &icmp_packet ) Socket.send_to( request_buffer.data(), DestinationEndpoint ); // Wait up to five seconds for a reply. - NumReplies = 0; + RepliesCount = 0; Timer.expires_at( TimeSent + posix_time::seconds( 5 ) ); Timer.async_wait( boost::bind( &BoostPinger::handle_timeout, this ) ); } void BoostPinger::handle_timeout() { - if ( NumReplies == 0 ) + if ( RepliesCount == 0 ) std::cout << "Request timed out" << std::endl; // Requests must be sent no less than one second apart. @@ -133,10 +157,10 @@ void BoostPinger::handle_receive( const std::size_t &length ) if ( is && icmp_packet.match( IcmpHeader::EchoReply, get_identifier(), SequenceNumber ) ) { // If this is the first reply, interrupt the five second timeout. - if ( NumReplies == 0 ) + if ( RepliesCount == 0 ) Timer.cancel(); - ++NumReplies; + ++RepliesCount; // Print out some information about the reply packet. print_echo_reply( icmp_packet, length ); @@ -153,12 +177,18 @@ void BoostPinger::print_echo_reply( Ipv4Header ipv4_hdr = icmp_packet.get_ip_header(); IcmpHeader icmp_hdr = icmp_packet.get_icmp_header(); + std::size_t bytes_received = length - ipv4_hdr.get_header_length(); + std::string source_address = ipv4_hdr.get_source_address().to_string(); + std::size_t sequence_number = icmp_hdr.get_sequence_number(); + std::size_t ttl = ipv4_hdr.get_time_to_live(); posix_time::ptime now = posix_time::microsec_clock::universal_time(); - std::cout << ( length - ipv4_hdr.get_header_length() ) << " bytes from " - << ipv4_hdr.get_source_address() << ": icmp_seq=" - << icmp_hdr.get_sequence_number() << ", ttl=" - << ipv4_hdr.get_time_to_live() << ", time=" - << (now - TimeSent).total_milliseconds() << " ms" << std::endl; + std::size_t time = (now - TimeSent).total_milliseconds(); + + std::cout << bytes_received << " bytes " + << "from " << source_address + << ": icmp_seq=" << sequence_number + << " ttl=" << ttl + << " time=" << time << " ms" << std::endl; } uint16_t BoostPinger::get_identifier() diff --git a/src/ping/boostpinger.h b/src/ping/boostpinger.h index 1fdccfe..ecd35d9 100644 --- a/src/ping/boostpinger.h +++ b/src/ping/boostpinger.h @@ -20,10 +20,17 @@ public: BoostPinger( boost::asio::io_service &io_service ); virtual ~BoostPinger(); - void ping( const std::string &destination ); + void ping( + const std::string &destination, + const std::size_t times_to_ping + ); private: + void start_pinger(); + void stop_pinger(); + void start_send(); + IcmpPacket create_echo_request_packet(); void send_echo_request( const IcmpPacket &icmp_packet ); void handle_timeout(); @@ -45,7 +52,11 @@ private: uint16_t SequenceNumber; boost::posix_time::ptime TimeSent; boost::asio::streambuf ReplyBuffer; - std::size_t NumReplies; + std::size_t RepliesCount; + std::size_t TimesToPingTotal; + + const std::size_t MinTimesToPing; + const std::size_t MaxTimesToPing; }; diff --git a/src/ping/pinger.h b/src/ping/pinger.h index 3d1035c..41a7b8b 100644 --- a/src/ping/pinger.h +++ b/src/ping/pinger.h @@ -13,7 +13,10 @@ public: Pinger(); virtual ~Pinger(); - virtual void ping( const std::string &destination ) = 0; + virtual void ping( + const std::string &destination, + const std::size_t times_to_ping + ) = 0; };