#include #include #include "MessageListener.h" MessageListener::MessageListener(QObject *parent) : QObject(parent) { listener = new QTcpServer(this); connection = 0; connect(listener, SIGNAL(newConnection()), this, SLOT(receivedConnection())); } MessageListener::~MessageListener() { stopListener(); if(connection) { closeConnection(); delete connection; } delete listener; } bool MessageListener::startListener(quint16 port) { if(listener->isListening()) return false; return listener->listen(QHostAddress::Any, port); } void MessageListener::stopListener() { listener->close(); } void MessageListener::closeConnection() { if(connection) { connection->disconnectFromHost(); emit disconnected(); } } void MessageListener::receivedConnection() { connection = listener->nextPendingConnection(); if(connection) { stopListener(); setupConnections(); emit connected(); } } void MessageListener::setupConnections() { connect(connection, SIGNAL(readyRead()), this, SLOT(receivedData())); connect(connection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleError(QAbstractSocket::SocketError))); } bool MessageListener::writeMessage(const QString &message) { if(!connection || connection->state() != QAbstractSocket::ConnectedState) return false; QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out << (quint16)0; out << message; out.device()->seek(0); out << (quint16)(block.size() - sizeof(quint16)); return connection->write(block) == block.size(); } void MessageListener::connectToHost(const QString &address, quint16 port) { if(connection && connection->state() == QAbstractSocket::ConnectedState) closeConnection(); if(!connection) { connection = new QTcpSocket(this); connect(connection, SIGNAL(connected()), this, SLOT(stopListener())); connect(connection, SIGNAL(connected()), this, SIGNAL(connected())); setupConnections(); } connection->connectToHost(address, port); } void MessageListener::receivedData() { static quint16 blockSize = 0; QDataStream in(connection); if(blockSize == 0) { if(connection->bytesAvailable() < (int)sizeof(quint16)) return; in >> blockSize; } if(connection->bytesAvailable() < blockSize) return; QString message; in >> message; blockSize = 0; emit receivedMessage(message); } void MessageListener::handleError(QAbstractSocket::SocketError error) { switch(error) { case QAbstractSocket::RemoteHostClosedError: emit disconnected(); break; case QAbstractSocket::NetworkError: case QAbstractSocket::UnknownSocketError: closeConnection(); break; default: emit connectionFailed(); } } QString MessageListener::remoteHost() const { if(connection) return connection->peerAddress().toString(); else return QString(); }