سؤال

لقد بدأت في إنشاء أول تطبيق متعدد الخيوط، باستخدام مكتبات 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_4_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()

ثم لا يمكن للخادم تلقي البيانات من قبل العميل.

هل يوجد لدى أحد أي فكرة؟

شكرا مقدما دانييلي

هل كانت مفيدة؟

المحلول

socket = this->nextPendingConnection();

يجب ان يكون:

socket = server->nextPendingConnection();

لأنك تستخدم server عضو وليس this كما النشطة QTcpServer, الفصل Connection لا ينبغي حتى أن ترث من QTcpServer, ولكن فقط من QObject.

كما أنك تسيء الاستخدام QThread.يجب أن تقرأ الإشارات والفتحات عبر المواضيع, ، وربما المواضيع ووحدة SQL, ، لو Db يستخدم وحدة QtSql.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top