Commit c7d5572c authored by Pavel Vainerman's avatar Pavel Vainerman

TCPCheck: добавил функцию ping (пока реализация через system).

parent e5096e35
......@@ -3,14 +3,12 @@
// -----------------------------------------------------------------------------
#include <atomic>
#include <cc++/socket.h>
#include "Mutex.h"
#include "ThreadCreator.h"
// -----------------------------------------------------------------------------
/*! Вспомогательный класс для проверки связи, реализованный через создание потока,
чтобы при проверке не было "зависания" при недоступности адреса.
Смысл: создаётся поток, в нём происходит проверка, а в вызвавший поток приостанавливается
на время timeout, по истечении которого созданный поток "принудительно"(в любом случае)
уничтожается..
на время timeout, по истечении которого созданный поток "принудительно"(в любом случае!) уничтожается..
*/
class TCPCheck
{
......@@ -18,19 +16,31 @@ class TCPCheck
TCPCheck();
~TCPCheck();
/*! Проверка связи с узлом
/*! Проверка связи с сервисом на определённом порту
* \param _ip - ip проверяемого узла
* \param _port - порт для проверяемого узла
* \param tout - таймаут на попытку
* \param sleep_msec - пауза между проверками результата
*
* Для проверки идёт попытка открыть соединение, но данные не посылаются, а соединение сразу закрывается.
* \note Нужно быть уверенным, что сервис не зависнет от таких попыток "соединений"
*/
bool check( const std::string& _ip, int _port, timeout_t tout, timeout_t sleep_msec = 50 );
/*! \param iaddr - 'ip:port' */
bool check( const std::string& iaddr, timeout_t tout, timeout_t sleep_msec = 50);
/*! Проверка связи с узлом командой ping
* \note Вызывается через system()! Это может быть опасно с точки зрения безопасности..
* \todo Возможно стоит написать свою реализацию ping
*/
bool ping( const std::string& _ip, timeout_t tout = 1000, timeout_t sleep_msec = 200, const std::string& ping_argc="-c 1 -w 0.1 -q -n" );
protected:
void check_thread();
void ping_thread();
void setResult( bool s )
{
......@@ -41,6 +51,8 @@ class TCPCheck
std::string ip = {""};
int port = {0};
int tout_msec;
std::string ping_args={"-c 1 -w 0.1 -q -n"};
};
// -----------------------------------------------------------------------------
#endif // _TCPCheck_H_
......
// -----------------------------------------------------------------------------
#include <sstream>
#include <cstdlib>
#include "UniSetTypes.h"
#include "PassiveTimer.h"
#include "TCPCheck.h"
......@@ -53,7 +54,6 @@ bool TCPCheck::check( const std::string& _ip, int _port, timeout_t tout, timeout
void TCPCheck::check_thread()
{
setResult(false);
try
{
ost::Thread::setException(ost::Thread::throwException);
......@@ -65,3 +65,39 @@ void TCPCheck::check_thread()
catch( ost::Exception& e ) {}
}
// -----------------------------------------------------------------------------
bool TCPCheck::ping( const std::string& _ip, timeout_t tout, timeout_t sleep_msec, const std::string& _ping_args )
{
ip = _ip;
tout_msec = tout;
ping_args = _ping_args;
setResult(false);
ThreadCreator<TCPCheck> t(this, &TCPCheck::ping_thread);
t.setCancel(ost::Thread::cancelDeferred);
t.start();
PassiveTimer pt(tout);
while( !pt.checkTime() && t.isRunning() )
msleep(sleep_msec);
if( t.isRunning() ) // !getResult() )
t.stop();
return result;
}
// -----------------------------------------------------------------------------
void TCPCheck::ping_thread()
{
setResult(false);
ostringstream cmd;
cmd << "ping " << ping_args << " " << ip << " 2>/dev/null 1>/dev/null";
int ret = system(cmd.str().c_str());
int res = WEXITSTATUS(ret);
setResult((res==0));
}
// -----------------------------------------------------------------------------
......@@ -26,7 +26,7 @@ bool run_test_server()
return true;
}
// --------------------------------------------------------
TEST_CASE("TCPCheck", "[tcpcheck]" )
TEST_CASE("TCPCheck::check", "[tcpcheck][tcpcheck_check]" )
{
TCPCheck t;
......@@ -45,3 +45,16 @@ TEST_CASE("TCPCheck", "[tcpcheck]" )
CHECK( res.get() );
}
// --------------------------------------------------------
TEST_CASE("TCPCheck::ping", "[tcpcheck][tcpcheck_ping]" )
{
TCPCheck t;
auto res = std::async(std::launch::async, run_test_server);
CHECK( t.ping(host) );
CHECK_FALSE( t.ping("dummy_host_name") );
cancel = true;
CHECK( res.get() );
}
// --------------------------------------------------------
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment