0
votes

I wrote a small server for tcp in qt, and moved to a second thread (easier to handle for me). The code for the server is:

#include "server.h"


Server::Server(QString ipAddr, quint32 port)
{
    Server::ipAddr = ipAddr;
    Server::port = port;
    firstTime = true;
    sessionOpened();
    qDebug() << "New server created (from Server)!";

    //connect(Server::tcpServer, SIGNAL(newConnection()), this, SLOT(createConnection()));
    qDebug() << "Connections created!";

}

void Server::showSignals()
{
    exit(0);
    qCritical() << m_pSignalSpy->wait(10000);
//    for(int index = 0; index<m_pSignalSpy->size(); index++)
//    {
//        QList<QVariant> listItem = m_pSignalSpy->value(index);

//        qDebug() << "Signal Arguments: ";
//        for(int index2 = 0;index2 < listItem.size();index2++)
//        {
//            qDebug() << listItem[index2].toString().toStdString()<<" ";
//        }
//    }
}

void Server::sessionOpened()
{
    Server::tcpServer = new QTcpServer(this);
    connect(tcpServer, &QTcpServer::newConnection, this, &Server:: gotAConnection);
    if(!Server::tcpServer->listen(QHostAddress::Any, (quint16)Server::port))
    {
        //QMessageBox::information(this, tr("Server"), tr("Unable to start the server: %1.").arg(Server::tcpServer->errorString()));
        Server::tcpServer->close();
        exit(0);
        return;
    }

    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    // use the first non-localhost IPv4 address
    for (int i = 0; i < ipAddressesList.size(); ++i) {
        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
                ipAddressesList.at(i).toIPv4Address()) {
            Server::ipAddr = ipAddressesList.at(i).toString();
            break;
        }
    }
    // if we did not find one, use IPv4 localhost
    if (Server::ipAddr.isEmpty())
        Server::ipAddr = QHostAddress(QHostAddress::LocalHost).toString();

    qDebug() << Server::ipAddr;
    qDebug() << Server::tcpServer->hasPendingConnections();
//    connect(Server::tcpServer, SIGNAL(newConnection()), this, SLOT(gotAConnection()));
//    Server::m_pSignalSpy = new QSignalSpy(Server::tcpServer, SIGNAL(newConnection()));
//    connect(Server::tcpServer, SIGNAL(newConnection()), this, SLOT(showSignals()));
}

void Server::getInfo()
{
    sendData("Hello");
}

void Server::destroyConnection()
{
    Server::clientConnection->disconnectFromHost();
}

void Server::gotAConnection()
{
    qDebug() << "Got new Connection!";
    exit(0);
}

void Server::createConnection()
{
    qDebug() << "Got new connection, more info later!";
    Server::clientConnection = tcpServer->nextPendingConnection();
    qDebug() << "Got new connection from " << Server::clientConnection->peerAddress().toString();
    emit Server::gotNewConnection(Server::clientConnection->peerAddress().toString());
}

void Server::sendData(QVariant data)
{
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    out << (quint16)0;
    out << data;// << '\n' << data.type();
    qCritical() << "Sending Data!";
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));
    connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));
    clientConnection->write(block);
}

void Server::closeServer()
{
    destroyConnection();
    return;
}

Server.h:

#ifndef SERVER_H
#define SERVER_H
#include <QTcpServer>
//#include <QtTest/QTest>
#include <QSignalSpy>
#include <QTcpSocket>
#include <QDebug>
//#include <QMessageBox>
#include <QNetworkInterface>
#include <typeinfo>
//#include <QSignalSpy>

class Server : public QObject
{
    Q_OBJECT
public slots:
    void sessionOpened();


    void getInfo();
    void closeServer();
    void createConnection();
    void gotAConnection(void);
    void destroyConnection();
    void sendData(QVariant data);
    void showSignals(void);
signals:
    void gotNewConnection(QString);
private:
    QTcpServer *tcpServer;
    QString ipAddr;
    quint32 port;
    QTcpSocket *clientConnection;
    quint32 BlockSize;
    bool firstTime;
    QSignalSpy * m_pSignalSpy;
//    template <typename t>
//    void getD
public:
    Server(QString ipAddr, quint32 port);
};

#endif // SERVER_H

I can run the server, and I connect to it (for example via Telnet), but tcpServer does not emit a signal once something is connected to it. Why? Did I do something wrong?
EDIT: Updated code added

1
You are inheriting from QTcpServer (class Server : public QTcpServer) as well as having an instance of QTcpServer (QTcpServer *tcpServer). Do you have a valid reason for doing this? Personally, I'd inherit from QObject and hold an instance of QTcpServerTheDarkKnight
Had no reason for that, fixed, but the problem still persists...arc_lupus
Please update the code in the question to represent the fix.TheDarkKnight

1 Answers

0
votes
connect(Server::tcpServer, SIGNAL(newConnection()), this, SLOT(gotAConnection()));

I believe this is the problem and the connection here is failing.

In order to connect, the first parameter should be the address of an instance of an object derived from QObject. The member tcpServer has not been instantiated, you should be connecting to the instance and calling it after creation of the QTcpServer object.

Remove the connect in the constructor and add it to the SessionOpened function, after the creation of the QTcpServer instance.

If you use C++11, you can also use the new connection syntax, which will warn you at compile time if there is a problem.

Server::tcpServer = new QTcpServer(this);
connect(tcpServer, &QTcpServer::newConnection, this, &Server:: gotAConnection);