Commit 04405ecf authored by Pavel Vainerman's avatar Pavel Vainerman

(ModbusTCPMaster): правки в обработке disconnect

(UTCPStream): сделал shutdown перед close (для корректного завершения соединения), добавил проверку на POCO_INVALID_SOCKET (SM): сделал чтобы SM вылетала в случае если настал activateTimeout.
parent b9994862
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
Name: libuniset2 Name: libuniset2
Version: 2.5 Version: 2.5
Release: alt14 Release: alt14.4
Summary: UniSet - library for building distributed industrial control systems Summary: UniSet - library for building distributed industrial control systems
License: LGPL License: LGPL
...@@ -486,6 +486,18 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -486,6 +486,18 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# .. # ..
%changelog %changelog
* Tue Sep 20 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14.4
- UTCPStream: check POCO_INVALID_SOCKET
* Mon Sep 19 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14.3
- UTCPStream: shudown and close (for disconnect)
* Mon Sep 19 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14.2
- (ModbusTCPMaster): added disconnect() function
* Mon Sep 19 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14.1
- (ModbusTCPMaster): added catch exceptions
* Mon Sep 12 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14 * Mon Sep 12 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14
- up build - up build
......
...@@ -124,6 +124,47 @@ TEST_CASE("MBTCPMaster: reconnect", "[modbus][mbmaster][mbtcpmaster]") ...@@ -124,6 +124,47 @@ TEST_CASE("MBTCPMaster: reconnect", "[modbus][mbmaster][mbtcpmaster]")
REQUIRE_FALSE(mb.isConnection()); REQUIRE_FALSE(mb.isConnection());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: forceDisconnect", "[modbus][mbmaster][mbtcpmaster][forceDisconnect]")
{
InitTest();
ModbusTCPMaster mb;
mb.setTimeout(500);
for( size_t i=0; i<1000; i++ )
{
// подключение к несуществующему адресу
REQUIRE_FALSE(mb.connect(iaddr, 2048));
try
{
mb.read03(slaveADDR,10,1);
}
catch(...){}
REQUIRE_FALSE(mb.isConnection());
mb.forceDisconnect();
}
}
// -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: disconnect", "[modbus][mbmaster][mbtcpmaster][disconnect]")
{
InitTest();
ModbusTCPMaster mb;
mb.setTimeout(500);
mb.setForceDisconnect(true);
for( size_t i=0; i<1000; i++ )
{
// подключение к несуществующему адресу
REQUIRE_FALSE(mb.connect(iaddr, 2048));
try
{
mb.read03(slaveADDR,10,1);
}
catch(...){}
REQUIRE_FALSE(mb.isConnection());
mb.disconnect();
}
}
// -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: 0x01 (read coil status)", "[modbus][0x01][mbmaster][mbtcpmaster]") TEST_CASE("MBTCPMaster: 0x01 (read coil status)", "[modbus][0x01][mbmaster][mbtcpmaster]")
{ {
InitTest(); InitTest();
......
...@@ -69,8 +69,6 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std: ...@@ -69,8 +69,6 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std:
msecPulsar(0), msecPulsar(0),
confnode(0) confnode(0)
{ {
mutex_start.setName(myname + "_mutex_start");
auto conf = uniset_conf(); auto conf = uniset_conf();
string cname(confname); string cname(confname);
...@@ -155,7 +153,7 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std: ...@@ -155,7 +153,7 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std:
evntPause = conf->getArgPInt("--e-startup-pause", 5000); evntPause = conf->getArgPInt("--e-startup-pause", 5000);
activateTimeout = conf->getArgPInt("--activate-timeout", 30000); activateTimeout = conf->getArgPInt("--activate-timeout", 60000);
sidPulsar = DefaultObjectId; sidPulsar = DefaultObjectId;
string p = conf->getArgParam("--pulsar-id", it.getProp("pulsar_id")); string p = conf->getArgParam("--pulsar-id", it.getProp("pulsar_id"));
...@@ -197,17 +195,21 @@ SharedMemory::~SharedMemory() ...@@ -197,17 +195,21 @@ SharedMemory::~SharedMemory()
void SharedMemory::timerInfo( const TimerMessage* tm ) void SharedMemory::timerInfo( const TimerMessage* tm )
{ {
if( tm->id == tmHeartBeatCheck ) if( tm->id == tmHeartBeatCheck )
{
checkHeartBeat(); checkHeartBeat();
}
else if( tm->id == tmEvent ) else if( tm->id == tmEvent )
{ {
workready = 1; workready = true;
// рассылаем уведомление, о том, чтобы стартанули // рассылаем уведомление, о том, чтобы стартанули
SystemMessage sm1(SystemMessage::WatchDog); SystemMessage sm1(SystemMessage::WatchDog);
sendEvent(sm1); sendEvent(sm1);
askTimer(tm->id, 0); askTimer(tm->id, 0);
} }
else if( tm->id == tmHistory ) else if( tm->id == tmHistory )
{
saveToHistory(); saveToHistory();
}
else if( tm->id == tmPulsar ) else if( tm->id == tmPulsar )
{ {
if( sidPulsar != DefaultObjectId ) if( sidPulsar != DefaultObjectId )
...@@ -241,11 +243,14 @@ void SharedMemory::sysCommand( const SystemMessage* sm ) ...@@ -241,11 +243,14 @@ void SharedMemory::sysCommand( const SystemMessage* sm )
} }
if( !activated ) if( !activated )
smcrit << myname << "(sysCommand): ************* don`t activate?! ************" << endl; {
smcrit << myname << "(sysCommand): Don`t activate! TERMINATE.." << endl;
std::terminate();
}
// подождать пока пройдёт инициализация // подождать пока пройдёт инициализация
// см. activateObject() // см. activateObject()
UniSetTypes::uniset_rwmutex_rlock l(mutex_start); std::unique_lock<std::mutex> lock(mutexStart);
askTimer(tmHeartBeatCheck, heartbeatCheckTime); askTimer(tmHeartBeatCheck, heartbeatCheckTime);
askTimer(tmEvent, evntPause, 1); askTimer(tmEvent, evntPause, 1);
...@@ -294,7 +299,7 @@ bool SharedMemory::activateObject() ...@@ -294,7 +299,7 @@ bool SharedMemory::activateObject()
{ {
activated = false; activated = false;
UniSetTypes::uniset_rwmutex_wrlock l(mutex_start); std::unique_lock<std::mutex> lock(mutexStart);
res = IONotifyController::activateObject(); res = IONotifyController::activateObject();
// инициализируем указатели // инициализируем указатели
...@@ -328,6 +333,7 @@ bool SharedMemory::activateObject() ...@@ -328,6 +333,7 @@ bool SharedMemory::activateObject()
} }
cout << myname << ": ********** activate: " << pt.getCurrent() << " msec " << endl; cout << myname << ": ********** activate: " << pt.getCurrent() << " msec " << endl;
sminfo << myname << ": ********** activate: " << pt.getCurrent() << " msec " << endl;
return res; return res;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
......
...@@ -417,7 +417,7 @@ class SharedMemory: ...@@ -417,7 +417,7 @@ class SharedMemory:
void buildEventList( xmlNode* cnode ); void buildEventList( xmlNode* cnode );
void readEventList( const std::string& oname ); void readEventList( const std::string& oname );
UniSetTypes::uniset_rwmutex mutex_start; std::mutex mutexStart;
class HeartBeatInfo class HeartBeatInfo
{ {
......
...@@ -44,6 +44,7 @@ class UTCPStream: ...@@ -44,6 +44,7 @@ class UTCPStream:
bool isSetLinger() const; bool isSetLinger() const;
void forceDisconnect(); // disconnect() без ожидания (с отключением SO_LINGER) void forceDisconnect(); // disconnect() без ожидания (с отключением SO_LINGER)
void disconnect();
// -------------------------------------------------------------------- // --------------------------------------------------------------------
int getSocket() const; int getSocket() const;
......
...@@ -59,7 +59,7 @@ void ModbusTCPMaster::setChannelTimeout( timeout_t msec ) ...@@ -59,7 +59,7 @@ void ModbusTCPMaster::setChannelTimeout( timeout_t msec )
Poco::Timespan tm = UniSetTimer::millisecToPoco(msec); Poco::Timespan tm = UniSetTimer::millisecToPoco(msec);
Poco::Timespan old = tcp->getReceiveTimeout();; Poco::Timespan old = tcp->getReceiveTimeout();;
if( old.microseconds() == tm.microseconds() ) if( old.totalMicroseconds() == tm.totalMicroseconds() )
return; return;
tcp->setReceiveTimeout(tm); tcp->setReceiveTimeout(tm);
...@@ -201,7 +201,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -201,7 +201,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
} }
cleanInputStream(); cleanInputStream();
tcp->forceDisconnect(); if( tcp )
tcp->forceDisconnect();
return erTimeOut; // return erHardwareError; return erTimeOut; // return erHardwareError;
} }
...@@ -247,12 +248,13 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -247,12 +248,13 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
if( force_disconnect ) if( force_disconnect )
{ {
if( dlog->is_info() ) if( dlog->is_info() )
dlog->info() << "(query): force disconnect.." << endl; dlog->info() << "(query): disconnect.." << endl;
// при штатном обмене..лучше дождаться конца "посылки".. // при штатном обмене..лучше дождаться конца "посылки"..
// поэтому применяем disconnect(), а не forceDisconnect() // поэтому применяем disconnect(), а не forceDisconnect()
// (с учётом выставленной опции setLinger(true)) // (с учётом выставленной опции setLinger(true))
tcp->close(); if( tcp )
tcp->disconnect();
} }
return res; return res;
...@@ -267,7 +269,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -267,7 +269,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
dlog->info() << "(query): force disconnect.." << endl; dlog->info() << "(query): force disconnect.." << endl;
// cleanInputStream(); // cleanInputStream();
tcp->forceDisconnect(); if( tcp )
tcp->forceDisconnect();
} }
return erTimeOut; return erTimeOut;
...@@ -303,7 +306,7 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg, ...@@ -303,7 +306,7 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
catch( const std::exception& e ) catch( const std::exception& e )
{ {
if( dlog->is_warn() ) if( dlog->is_warn() )
dlog->crit() << "(query): " << e.what() << std::endl; dlog->warn() << "(query): " << e.what() << std::endl;
} }
return erTimeOut; // erHardwareError return erTimeOut; // erHardwareError
...@@ -385,7 +388,7 @@ bool ModbusTCPMaster::connect( const std::string& addr, int _port, bool closeOld ...@@ -385,7 +388,7 @@ bool ModbusTCPMaster::connect( const std::string& addr, int _port, bool closeOld
{ {
ostringstream s; ostringstream s;
s << "(ModbusTCPMaster): connect " << iaddr << ":" << port << " error: " << e.what(); s << "(ModbusTCPMaster): connect " << iaddr << ":" << port << " error: " << e.what();
dlog->crit() << iaddr << std::endl; dlog->crit() << s.str() << std::endl;
} }
} }
...@@ -426,13 +429,22 @@ bool ModbusTCPMaster::connect( const Poco::Net::SocketAddress& addr, int _port, ...@@ -426,13 +429,22 @@ bool ModbusTCPMaster::connect( const Poco::Net::SocketAddress& addr, int _port,
tcp->setNoDelay(true); tcp->setNoDelay(true);
return true; return true;
} }
catch( Poco::TimeoutException& ex)
{
if( dlog->debugging(Debug::CRIT) )
{
ostringstream s;
s << "(ModbusTCPMaster): create connection " << iaddr << ":" << port << " timeout exception";
dlog->crit() << s.str() << std::endl;
}
}
catch( Poco::Net::NetException& ex) catch( Poco::Net::NetException& ex)
{ {
if( dlog->debugging(Debug::CRIT) ) if( dlog->debugging(Debug::CRIT) )
{ {
ostringstream s; ostringstream s;
s << "(ModbusTCPMaster): create connection " << iaddr << ":" << port << " error: " << ex.displayText(); s << "(ModbusTCPMaster): create connection " << iaddr << ":" << port << " error: " << ex.displayText();
dlog->crit() << iaddr << std::endl; dlog->crit() << s.str() << std::endl;
} }
} }
catch( const std::exception& e ) catch( const std::exception& e )
...@@ -441,7 +453,7 @@ bool ModbusTCPMaster::connect( const Poco::Net::SocketAddress& addr, int _port, ...@@ -441,7 +453,7 @@ bool ModbusTCPMaster::connect( const Poco::Net::SocketAddress& addr, int _port,
{ {
ostringstream s; ostringstream s;
s << "(ModbusTCPMaster): connection " << iaddr << ":" << port << " error: " << e.what(); s << "(ModbusTCPMaster): connection " << iaddr << ":" << port << " error: " << e.what();
dlog->crit() << iaddr << std::endl; dlog->crit() << s.str() << std::endl;
} }
} }
catch( ... ) catch( ... )
...@@ -466,7 +478,7 @@ void ModbusTCPMaster::disconnect() ...@@ -466,7 +478,7 @@ void ModbusTCPMaster::disconnect()
if( !tcp ) if( !tcp )
return; return;
tcp->close(); tcp->disconnect(); // close();
tcp = nullptr; tcp = nullptr;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
......
...@@ -76,7 +76,7 @@ void TCPCheck::check_thread() ...@@ -76,7 +76,7 @@ void TCPCheck::check_thread()
t.create(ip, port, tout_msec); t.create(ip, port, tout_msec);
t.setKeepAliveParams( (tout_msec > 1000 ? tout_msec / 1000 : 1) ); t.setKeepAliveParams( (tout_msec > 1000 ? tout_msec / 1000 : 1) );
setResult(true); setResult(true);
t.close(); t.disconnect();
} }
catch( ... ) {} catch( ... ) {}
} }
......
...@@ -5,7 +5,11 @@ using namespace std; ...@@ -5,7 +5,11 @@ using namespace std;
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
USocket::~USocket() USocket::~USocket()
{ {
close(); try
{
close();
}
catch(...){}
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
USocket::USocket( int sock ) USocket::USocket( int sock )
......
...@@ -12,7 +12,11 @@ using namespace std; ...@@ -12,7 +12,11 @@ using namespace std;
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
UTCPSocket::~UTCPSocket() UTCPSocket::~UTCPSocket()
{ {
Poco::Net::ServerSocket::close(); try
{
Poco::Net::ServerSocket::close();
}
catch(...){}
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
UTCPSocket::UTCPSocket() UTCPSocket::UTCPSocket()
......
...@@ -57,20 +57,40 @@ bool UTCPStream::isSetLinger() const ...@@ -57,20 +57,40 @@ bool UTCPStream::isSetLinger() const
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void UTCPStream::forceDisconnect() void UTCPStream::forceDisconnect()
{ {
if( !isConnected() )
return;
try try
{ {
bool on;
int sec;
Poco::Net::StreamSocket::getLinger(on, sec);
setLinger(false, 0); setLinger(false, 0);
}
// catch( Poco::Net::NetException& ex ){}
catch( std::exception& ex ){}
try
{
close(); close();
//shutdown(); //shutdown();
Poco::Net::StreamSocket::setLinger(on, sec);
} }
catch( Poco::Net::NetException& ) // catch( Poco::Net::NetException& ex ){}
catch( std::exception& ex ){}
}
// -------------------------------------------------------------------------
void UTCPStream::disconnect()
{
try
{ {
shutdown();
}
// catch( Poco::Net::NetException& ex ){}
catch( std::exception& ex ){}
try
{
close();
} }
// catch( Poco::Net::NetException& ex ){}
catch( std::exception& ex ){}
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
int UTCPStream::getSocket() const int UTCPStream::getSocket() const
...@@ -81,13 +101,13 @@ int UTCPStream::getSocket() const ...@@ -81,13 +101,13 @@ int UTCPStream::getSocket() const
timeout_t UTCPStream::getTimeout() const timeout_t UTCPStream::getTimeout() const
{ {
auto tm = Poco::Net::StreamSocket::getReceiveTimeout(); auto tm = Poco::Net::StreamSocket::getReceiveTimeout();
return tm.microseconds(); return tm.totalMicroseconds();
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void UTCPStream::create(const std::string& hname, int port, timeout_t tout_msec ) void UTCPStream::create( const std::string& hname, int port, timeout_t tout_msec )
{ {
Poco::Net::SocketAddress sa(hname, port); Poco::Net::SocketAddress saddr(hname, port);
connect(sa, tout_msec * 1000); connect(saddr, UniSetTimer::millisecToPoco(tout_msec));
setKeepAlive(true); setKeepAlive(true);
Poco::Net::StreamSocket::setLinger(true, 1); Poco::Net::StreamSocket::setLinger(true, 1);
setKeepAliveParams(); setKeepAliveParams();
...@@ -95,7 +115,7 @@ void UTCPStream::create(const std::string& hname, int port, timeout_t tout_msec ...@@ -95,7 +115,7 @@ void UTCPStream::create(const std::string& hname, int port, timeout_t tout_msec
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
bool UTCPStream::isConnected() noexcept bool UTCPStream::isConnected() noexcept
{ {
return ( Poco::Net::StreamSocket::sockfd() > 0 ); return ( Poco::Net::StreamSocket::sockfd() != POCO_INVALID_SOCKET );
/* /*
try try
{ {
......
...@@ -132,8 +132,7 @@ void LogReader::disconnect() ...@@ -132,8 +132,7 @@ void LogReader::disconnect()
try try
{ {
//tcp->shutdown(); tcp->disconnect();
tcp->close();
} }
catch( const Poco::Net::NetException& e ) catch( const Poco::Net::NetException& e )
{ {
......
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