Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/MeteoDataManagement/tcpsocket.cpp
T
torstenandCopilot b774f4035c Qt6 Migration: DDS-Stubs, Logger-Fixes, Export-Header Korrekturen
- NGL_ADD_LIBRARY2: 87 CMakeLists.txt konvertiert für Export-Header Generierung
- 44 Export-Header Include-Pfade korrigiert (_export.h)
- 81 DDS-Stub-Header generiert (*_dtc.h, *_fts.h, *_dts.h, *_ftc.h)
- INGLLogger: Duplikat gelöscht, m_logger Member entfernt, variadische Makros
- Q_FUNC_INFO Redefinition behoben (Qt6 definiert bereits)
- FATAL_LOG Makro hinzugefügt
- InfrastructureManagement DDS-Stubs (ism.hpp, ism_enums.hpp, ism_ftc.h)
- FilterManagement DDS-Stubs (flt_ftc.h, flt_dts.h)
- AreaEffectSimulation DDS-Stubs (aes.hpp, aes_enums.hpp)
- SymbolAppearance Klasse vollständig definiert mit content() Methode
- BuildingComponentFilter Klasse definiert mit Copy-Konstruktor
- Ftc Factory: nullptr Return (abstract class)
- AesFilter Klasse in aes.hpp hinzugefügt
- Dtc Klasse in ppm.hpp mit participantChanged Signal
- AesType Enum: alle 15 At* Werte definiert
- AesEffectState_def: EsReceived hinzugefügt
- DataModification Enum: eAdded/eModified/eRemoved
- function_reply_object.h → core_types.h Include-Pfad (72 Dateien)
- Enum-Class-Streaming Template-Operator in INGLLogger.h
- ism_mounting_point.h: QImage → QtGui/QImage, QGuiApplication/QScreen
- ism_data_plugin_interface.h: QSet Include, Include-Reihenfolge
- QRegExp → QRegularExpression in tpm_js_parser.cpp
- .underlying() Aufrufe zu direktem Enum-Vergleich korrigiert
- Include-Pfade: aes.hpp in symbol_appearance_settings_impl.h und aes_display_filter_impl.h

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-19 06:06:24 +02:00

220 lines
6.8 KiB
C++
Executable File

/**
* TcpSocket handling for MeteoDataUnit
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2016-09-22
*/
#include "tcpsocket.h"
#include <QTimer>
#include <QHostInfo>
//#include <sys/socket.h> // used for keepalive
//#include <netinet/tcp.h> // used for keepalive
//#include <netinet/in.h> // used for keepalive
namespace MeteoDataManagement
{
TcpSocket::TcpSocket(const char *logName, QObject *parent)
: QObject(parent)
, m_waitTime(1)
, m_socket(nullptr)
, m_tryReconnect(false)
, m_bSocketErrorWarnedOnce(false)
, m_logger(getLogger(logName))
{
DEBUG_LOG() << "CTOR TCP-Socket... " ;
doConnect();
}
//-------------------------------------------------------------------
TcpSocket::~TcpSocket()
{
if (m_socket)
m_socket->close();
delete m_socket;
}
//-------------------------------------------------------------------
void TcpSocket::doConnect()
{
DEBUG_LOG() << "doConnect TCP-Socket " ;
if (m_socket)
m_socket->deleteLater();
m_socket = new QTcpSocket(this);
connect(m_socket, &QTcpSocket::connected,
this, &TcpSocket::onConnected);
connect(m_socket, &QTcpSocket::disconnected,
this, &TcpSocket::onDisonnected);
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
this, &TcpSocket::onError);
connect(m_socket, &QTcpSocket::readyRead,
this, &TcpSocket::onReadyRead);
if (m_tryReconnect)
{
INFO_LOG() << "Try reconnect to host " << m_hostName
<< ":" << m_hostPort;
m_socket->connectToHost(m_hostName, m_hostPort);
}
}
//-------------------------------------------------------------------
void TcpSocket::start(const QString &hostName, quint16 port)
{
INFO_LOG() << "Try connect to host: " << hostName
<< ": " << port;
m_hostName = hostName;
m_hostPort = port;
m_socket->connectToHost(m_hostName, port);
}
//-------------------------------------------------------------------
void TcpSocket::onConnected()
{
INFO_LOG() << "Connected to "
<< m_socket->peerAddress().toString()
<< ":" << m_socket->peerPort();
m_bSocketErrorWarnedOnce = false;
m_waitTime = 1;
// Bei einer TCP Verbindung ergibt sich ein Problem bei der Pruefung ob die Verbindung noch besteht.
// Das sollte mit Hilfe des 'TCP keepalive Mechanismus' behoben werden.
// Infos dazu u.A. unter http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/#intro
// Leider fuehrte keine der Varianten zum Erfolg.
// Der Abbruch wurde unabhaengig der Parameter in allen Faellen immer nach ziemlich genau 15:40Min dedektiert.
// Das Setzen der Systemvariablen war ebenfalls ohne Auswirkung.
// Da diese Programmteile unter Windows eh so nicht zu uebersetzen sind, ist der Codeteil hier in Kommentar gesetzt.
// INFO_LOG() << "----Set TCP_KEEPIDLE parameter ";
// const int keepAliveOption = 1; // on
// if (setsockopt(m_socket->socketDescriptor(), SOL_SOCKET, SO_KEEPALIVE, &keepAliveOption, sizeof(keepAliveOption)) != 0)
// {
// ERROR_LOG() << "Error setting SO_KEEPALIVE: " << errno;
// }
// const int idleTimeout = 5; // sec
// if (setsockopt(m_socket->socketDescriptor(), SOL_TCP, TCP_KEEPIDLE, &idleTimeout, sizeof(idleTimeout)) != 0)
// {
// ERROR_LOG() << "Error setting TCP_KEEPIDLE: " << errno;
// }
// const int keepIntervalCnt = 10; // sec
// if (setsockopt(m_socket->socketDescriptor(), SOL_TCP, TCP_KEEPINTVL, &keepIntervalCnt, sizeof(keepIntervalCnt)) != 0)
// {
// ERROR_LOG() << "Error setting TCP_KEEPINTVL: " << errno;
// }
// const int idlePaketCnt = 2; // 2 probes -> detection shoud be comes after 5s + 2 * 10s => 25 sec
// if (setsockopt(m_socket->socketDescriptor(), SOL_TCP, TCP_KEEPCNT, &idlePaketCnt, sizeof(idlePaketCnt)) != 0)
// {
// ERROR_LOG() << "Error setting TCP_KEEPCNT: " << errno;
// }
// //----- Testausgaben
// int getOption = 0;
// socklen_t optlen = sizeof(getOption);
// getsockopt(m_socket->socketDescriptor(), SOL_SOCKET, SO_KEEPALIVE, &getOption, &optlen);
// ERROR_LOG() << "...SO_KEEPALIVE set to: " << getOption;
// getsockopt(m_socket->socketDescriptor(), SOL_TCP, TCP_KEEPIDLE, &getOption, &optlen);
// ERROR_LOG() << "...TCP_KEEPIDLE set to: " << getOption;
// getsockopt(m_socket->socketDescriptor(), SOL_TCP, TCP_KEEPINTVL, &getOption, &optlen);
// ERROR_LOG() << "...TCP_KEEPINTVL set to: " << getOption;
// getsockopt(m_socket->socketDescriptor(), SOL_TCP, TCP_KEEPCNT, &getOption, &optlen);
// ERROR_LOG() << "...TCP_KEEPCNT set to: " << getOption;
init(); // pure virtual function
// Auspraegung mit spezieller Sensorinitialisierung durchfuehren
}
//-------------------------------------------------------------------
void TcpSocket::onDisonnected()
{
INFO_LOG() << "Disconnected from " << m_socket->peerAddress().toString()
<< ":" << m_socket->peerPort();
}
//-------------------------------------------------------------------
void TcpSocket::onError(QAbstractSocket::SocketError err)
{
ERROR_LOG() << "Socket error: " << err
<< " \"" << m_socket->errorString() << "\""
<< " Hostname: " << m_hostName
<< " Serial Port:" << m_hostPort
<< " - trying to reconnect in " << m_waitTime << " seconds";
m_socket->disconnectFromHost();
// try reconnects ....
m_tryReconnect = true;
if (m_socket->state() != QAbstractSocket::UnconnectedState)
m_socket->waitForDisconnected();
m_waitTime += 2;
if (m_waitTime > 120)
m_waitTime = 120;
QTimer::singleShot(m_waitTime * 1000, this, &TcpSocket::doConnect);
}
//-------------------------------------------------------------------
void TcpSocket::onReadyRead()
{
// zeilenweises Einlesen der Sensordaten
while (m_socket->canReadLine())
{
const QByteArray line = m_socket->readLine();
DEBUG_LOG() << "Read line from sensor: " << line;
dataAvailable(line); // pure virtual function
// Auspraegung mit spezieller Sensordatenauswertung durchfuehren
}
}
//-------------------------------------------------------------------
bool TcpSocket::sendCommand(const QByteArray &qba)
{
bool bOk = true;
INFO_LOG() << "Send command: " << qba;
if (m_socket->state() != QTcpSocket::ConnectedState)
{
if (m_bSocketErrorWarnedOnce)
{
m_bSocketErrorWarnedOnce = true;
WARNING_LOG() << "Error on sendCommand(). No socket connection estabilished."
<< " Hostname: " << m_hostName;
}
return false;
}
int trxBytes = m_socket->write(qba);
if (trxBytes != qba.size())
{
bOk = false;
ERROR_LOG() << "Insufficient number of tansfered bytes."
<< " Soll: " << trxBytes << " Ist: " << qba.size();
}
m_socket->flush();
return bOk;
}
//-------------------------------------------------------------------
} // namespace MeteoDataManagement