Соединение (в проекте QT) не работает

Я начинаю создавать свое первое многопоточное приложение, используя библиотеки QT.

Следуя руководству qt о QTcpServer и QTcpSocket, я написал серверное приложение, которое создает соединение с этим конструктором:

Connection::Connection(QObject *parent) : QTcpServer(parent)
{
    server = new QTcpServer();
    QString ipAddress;

    if (ipAddress.isEmpty())
        ipAddress = QHostAddress(QHostAddress::LocalHost).toString();

    if (!server->listen(QHostAddress(ipAddress),41500))
    {
        qDebug() << "Enable to start server";
        server->close();
        return;
    }

    connect(server,SIGNAL(newConnection()),this,SLOT(incomingConnection()));
}

Это функция incomingConnection(), которая создает новый поток каждый раз, когда новый клиент пытается подключиться:

void Connection::incomingConnection()
{
    QTcpSocket *socket = new QTcpSocket();
    socket = this->nextPendingConnection();

    MyThreadClass *thread = new MyThreadClass(socket, server);
    qDebug() << "connection required by client";
    if (thread != 0)
    {
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    thread->start();
    }
    else
        qDebug() << "Error: Could not create server thread.";
}

Теперь это MyThreadClass:

MyThreadClass::MyThreadClass(QTcpSocket *socket, QTcpServer *parent) : QThread(parent)
{
    tcpSocket = new QTcpSocket();
    database = new Db();
    blockSize = 0;

    tcpSocket = socket;

    qDebug() << "creating new thread";
}


MyThreadClass::~MyThreadClass()
{
    database->~Db();
}


void MyThreadClass::run()
{
    qDebug() << "Thread created";
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(dataAvailable()));
    exec();
}


void MyThreadClass::dataAvailable()
{
    qDebug() << "data available";
    QDataStream in(tcpSocket);
    in.setVersion(QDataStream::Qt
QObject::connect: Cannot connect (null)::readyRead() to QThread::dataAvailable()
0); if (blockSize == 0) { if (tcpSocket->bytesAvailable() < (int)sizeof(qint16)) return; in >> blockSize; } if (tcpSocket->bytesAvailable() < blockSize) return; QString string; in >> string; //[...] }

Код компилируется нормально, но когда я запускаю клиент (после запуска сервера), я получаю следующую ошибку на сервере:

QObject::connect: Cannot connect (null)::readyRead() to QThread::dataAvailable()

Тогда сервер не может получить данные от клиента.

Кто-нибудь знает?

заранее спасибо Даниэле


person Daniele    schedule 22.05.2012    source источник
comment
Я не уверен, но я думаю, что socket принадлежит первому потоку, и вы передаете его через вновь созданный поток, а внутри вы делаете tcpSocket = new QTcpSocket();, который, похоже, не может перераспределить данные вне текущего потока.   -  person sorush-r    schedule 23.05.2012
comment
Где вы изучали С++? Вы знаете что-нибудь о куче и стеке? У тебя утечка памяти. Также вы вызываете деструктор вручную вместо удаления. Другое дело, что даже если подключение к readyRead будет работать нормально, ваш слот будет вызываться в другом потоке, чем вы ожидаете. В вашем коде есть много вещей, которые нужно исправить. Также не могли бы вы предоставить объявление MyThreadClass? На вашем месте я бы начал с изучения некоторых основ C++ (например, управление памятью). Вы делаете так много вещей неправильно, что я бы даже не стал беспокоиться о вашей проблеме с подключением, пока вы не освоите основы C ++.   -  person Kamil Klimek    schedule 23.05.2012
comment
tcpSocket = new QTcpSocket();, а затем tcpSocket = socket;. Почему??? Почему ты бы так поступил??   -  person dschulz    schedule 23.05.2012
comment
ты прав. Этот код является результатом многих изменений, поэтому в нем много ошибок... извините за это... Однако, если отменить tcpSocket = new QTcpSocket(); Инструкция, проблема не меняется...   -  person Daniele    schedule 23.05.2012
comment
почему вы создаете QTcpServer, когда наследуете его? это неловко!! я не упоминаю другие проблемы, потому что кто-то уже сказал вам... много изменений не повод оставлять в коде такой мусор!   -  person andrea.marangoni    schedule 23.05.2012


Ответы (1)


socket = this->nextPendingConnection();

должно быть:

socket = server->nextPendingConnection();

поскольку вы используете член server, а не this в качестве активного QTcpServer, класс Connection не должен наследоваться даже от QTcpServer, а только от QObject.

Кроме того, вы неправильно используете QThread. Вы должны прочитать Сигналы и слоты между потоками и, возможно, Потоки и модуль SQL, если Db использует QtSql-модуль.

person alexisdm    schedule 23.05.2012
comment
Эта ошибка связана с плохим знанием C++. Вот почему я не указал это в начале. - person Kamil Klimek; 23.05.2012
comment
#Kamil Klimek: Я знаю это, потому что я изучал C++ в одиночку. Наверное, если бы я так же хорошо знал C++, как и вы, то мне не нужно было бы здесь ничего спрашивать. Кроме того, если вы не хотите, никто не заставляет вас отвечать - person Daniele; 23.05.2012
comment
#alexisdm: Большое спасибо. Я знал, что было много ошибок, но, следуя вашим советам, сейчас проект идет достаточно хорошо. На самом деле сервер и клиент общаются так, как я хочу. - person Daniele; 23.05.2012