/** * $Id$ * $HeadURL$ * $Author$ */ #include "tcpsocket.h" #include #include #include namespace DifferentialGPS { TcpSocket::TcpSocket(const char *logName) : QThread() , m_socket(nullptr) , m_logger(getLogger(logName)) , m_waitTime(1) , m_reconnectTimer(nullptr) { qRegisterMetaType("QAbstractSocket::SocketError"); moveToThread(this); } TcpSocket::~TcpSocket() { cleanupObject(); // just to be sure } void TcpSocket::startThreadInternal(const QString &hostName, quint16 port) { m_hostName = hostName; m_hostPort = port; start(); } void TcpSocket::run() { DEBUG_LOG(m_logger) << "Starting thread"; m_reconnectTimer = new QTimer(this); doConnect(); exec(); cleanupObject(); } void TcpSocket::doConnect() { 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::onDisconnected); connect(m_socket, QOverload::of(&QTcpSocket::error), this, &TcpSocket::onError); connect(m_socket, &QTcpSocket::readyRead, this, &TcpSocket::onReadyRead); INFO_LOG(m_logger) << "Connecting to tcp server at " << m_hostName << ":" << m_hostPort; m_socket->connectToHost(m_hostName, m_hostPort); } void TcpSocket::onConnected() { INFO_LOG(m_logger) << "Connected to " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort(); m_waitTime = 1; } void TcpSocket::onDisconnected() { INFO_LOG(m_logger) << "Disconnected from " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort(); } void TcpSocket::onError(QAbstractSocket::SocketError err) { ERROR_LOG(m_logger) << "Socket error: " << err << " " << m_socket->errorString() << ":" << m_socket->peerPort() << " - trying to reconnect in " << m_waitTime << " seconds"; m_socket->disconnectFromHost(); if (m_socket->state() != QAbstractSocket::UnconnectedState) m_socket->waitForDisconnected(); m_waitTime += 2; if (!m_reconnectTimer->isActive()) m_reconnectTimer->start(m_waitTime * 1000); if (m_waitTime > 120) m_waitTime = 120; } void TcpSocket::cleanupObject() { if (m_reconnectTimer) { m_reconnectTimer->disconnect(this); delete m_reconnectTimer; m_reconnectTimer = nullptr; } if (m_socket) { m_socket->disconnect(this); m_socket->close(); if (m_socket->state() != QAbstractSocket::UnconnectedState) m_socket->waitForDisconnected(); delete m_socket; m_socket = nullptr; } } } // namespace DifferentialGPS