arc_lupus
arc_lupus

Reputation: 4114

Connection to server fails in qt

I created a small server/client application, and for testing I put the server/client function into a separate application. The main client functions are

Client::Client(QString purpose) : networkSession(0)
{
    Client::purpose = purpose;
    tcpSocket = new QTcpSocket;
    Client::blockSize = 0;
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readData()));
    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(displayError(QAbstractSocket::SocketError)));

    QNetworkConfigurationManager manager;
    if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)
    {
        // Get saved network configuration
        QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
        settings.beginGroup(QLatin1String("QtNetwork"));
        const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
        settings.endGroup();

        // If the saved network configuration is not currently discovered use the system default
        QNetworkConfiguration config = manager.configurationFromIdentifier(id);
        if ((config.state() & QNetworkConfiguration::Discovered) !=
            QNetworkConfiguration::Discovered) {
            config = manager.defaultConfiguration();
        }

        networkSession = new QNetworkSession(config, this);
        connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened()));
    }
    qDebug() << "Client set up, waiting";
}

void Client::connectToServer(QString ipAddr, quint32 port)
{
    qDebug() << "Connecting to Host on port " << port << ' ' << (quint16)port;
    tcpSocket->connectToHost(ipAddr, port);
    emit this->connectionResult((tcpSocket->state() == QAbstractSocket::UnconnectedState)?false:true);
    if (tcpSocket->waitForConnected(1000))
        qDebug("Connected!");
    qDebug() << "Am I connected" << tcpSocket->state();
    std::cout << "Am I not connected" << tcpSocket->state();
}

and the server-functions:

Server::Server(QString ipAddr, quint32 port, QString purpose)
:  tcpServer(0), networkSession(0)
{
    Server::clientConnection = NULL;
    Server::purpose = purpose;
    Server::port = port;
    QNetworkConfigurationManager manager;
    if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
        // Get saved network configuration
        QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
        settings.beginGroup(QLatin1String("QtNetwork"));
        const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
        settings.endGroup();

        // If the saved network configuration is not currently discovered use the system default
        QNetworkConfiguration config = manager.configurationFromIdentifier(id);
        if ((config.state() & QNetworkConfiguration::Discovered) !=
            QNetworkConfiguration::Discovered) {
            config = manager.defaultConfiguration();
        }

        networkSession = new QNetworkSession(config, this);
        connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened()));

        //statusLabel->setText(tr("Opening network session."));
        networkSession->open();
    } else {
        sessionOpened();
    }
        //connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFortune()));
        connect(tcpServer, SIGNAL(newConnection()), this, SLOT(openNewConnection()));
        //connect(tcpServer, &QTcpServer::newConnection, this, &Server::openNewConnection);
}

void Server::sessionOpened()
{
    // Save the used configuration
    if (networkSession) {
        QNetworkConfiguration config = networkSession->configuration();
        QString id;
        if (config.type() == QNetworkConfiguration::UserChoice)
            id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString();
        else
            id = config.identifier();

        QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
        settings.beginGroup(QLatin1String("QtNetwork"));
        settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
        settings.endGroup();
    }

    tcpServer = new QTcpServer(this);
    if (!tcpServer->listen(QHostAddress::Any, Server::port)) {
        return;
    }
    qDebug() << "Server listening on: " << tcpServer->serverPort();
//! [0]
    QString ipAddress;
    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()) {
            ipAddress = ipAddressesList.at(i).toString();
            break;
        }
    }
    // if we did not find one, use IPv4 localhost
    if (ipAddress.isEmpty())
        ipAddress = QHostAddress(QHostAddress::LocalHost).toString();

//! [1]
}

void Server::openNewConnection(void)
{
    qDebug() << "New conn incoming!";
    Server::clientConnection = tcpServer->nextPendingConnection();
    QVariant ipAddr_QVar(clientConnection->peerAddress().toString());
    qDebug() << "Got new connection!";
    emit gotNewConnection(ipAddr_QVar);
}

The main problem here is that even if I get a "Connected" from

if (tcpSocket->waitForConnected(1000))
    qDebug("Connected!");
qDebug() << "Am I connected" << tcpSocket->state();

in the client function, but the server function openNewConnection() never gets called. Why? How can I find the bug? If a minimal working example is necessary, I can provide the whole code, but here I just wanted to provide the most important functions.

Edit:
client.h:

#ifndef CLIENT_H
#define CLIENT_H

//#include <QDialog>
#include <iostream>
#include <QTcpSocket>

class QComboBox;
class QDialogButtonBox;
class QLabel;
class QLineEdit;
class QPushButton;
class QTcpSocket;
class QNetworkSession;

class Client : public QObject
{
    Q_OBJECT
private:
    QTcpSocket *tcpSocket;
    QString currentFortune;
    quint16 blockSize;
    QPair<QString, QPair<QString, QVariant> > data;
    QNetworkSession *networkSession;
    QString purpose;

signals:
    void gotData(QPair<QString, QPair<QString, QVariant> >);
    void noConnection(void);
    void connectionResult(bool);
    void isDisconnect(bool);
public slots:
    void displayError(QAbstractSocket::SocketError socketError);
    void sessionOpened();
    void getInfo();
    void readData();
    void connectToServer(QString ipAddr, quint32 port);
    void disconnectFromServer();
private:

public:


    Client(QString purpose);
};

#endif // CLIENT_H

server.h:

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

QT_BEGIN_NAMESPACE
class QTcpServer;
class QNetworkSession;
QT_END_NAMESPACE

class Server : public QObject
{
    Q_OBJECT
public slots:
    void sessionOpened();
    void sendFortune(void);
    void sendData(QPair<QString, QPair<QString, QVariant> > data);
    void sendFile(QVariant fileName);
    void disconnectServer(void);
    void openNewConnection(void);
signals:
    void gotNewConnection(QVariant);
private:
    QString purpose;
    QTcpServer *tcpServer;
    QString ipAddr;
    quint32 port;
    QTcpSocket *clientConnection;
    quint32 BlockSize;
    bool firstTime;
    QSignalSpy * m_pSignalSpy;
    QStringList fortunes;
    QNetworkSession *networkSession;
    //QNetworkConfiguration config;
public:
    Server(QString ipAddr, quint32 port, QString purpose = "");
};

#endif // SERVER_H

Upvotes: 0

Views: 927

Answers (1)

Jake Wade
Jake Wade

Reputation: 601

The problem lies with your QNetworkSession, you have declared it in scope. Meaning once you leave that function the QNetworkSession gets destroyed. A destroyed object cannot emit a signal. Maybe make it a member variable or construct it in your header.

Upvotes: 1

Related Questions