2016-07-19 13 views
0

aufrufen Ich lerne über Multi-threaded Programmierung in Qt, und während ich die Schreibfunktion der QTcpSocket Klasse von einem QThread aufrufen. Die Funktion Ausgang:Ein Fehler ausgelöst, während ich die Schreibfunktion der QTcpSocket-Klasse von einem QThread

QObject: Cannot create children for a parent that is in a different thread. 
(Parent is QNativeSocketEngine(0x6f1840), parent's thread is QThread(0x624e90), current thread is QThread(0x716ed0) 

der Code, den ich die Schreibfunktion genannt:

QString Processor::GetSystemInfoOfClient() const 
{ 
    QString result; 
    const char *send_buffer = "GSIOC"; 
    char receive_buffer[100]; 
    this->cli_sock->write(send_buffer); 
    this->cli_sock->waitForBytesWritten(); 
    this->cli_sock->waitForReadyRead(100000); 
    this->cli_sock->read(receive_buffer, 100); 
    result = QString(receive_buffer); 
    return result; 
} 

der Code, den ich die Verbindungen annehmen:

Die Definition des Verbindungsprozessor:

class Processor : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit Processor(QObject *parent = 0, QTcpServer *server = nullptr); 
private: 
    QTcpServer *m_server = nullptr; 
    QTcpSocket *cli_sock = nullptr; 
    QHostAddress cli_addr; 
    quint16 cli_port; 

    QString GetSystemInfoOfClient() const; 
signals: 
    void GetDetailedFinished(const QString &address,const QString &port, const QString &SystemInfo); 
public slots: 
    void GetClientDetail(); 
    void Accept(); 
}; 

Dann bewege ich den Prozessor zum QThread

Processor *processor = new Processor(0, server); 
    processor->moveToThread(&processor_thread); 
    connect(&processor_thread, &QThread::finished, processor, &QObject::deleteLater); 
    connect(this, &Processor_Controller::Accept, processor, &Processor::Accept); 
    connect(this, &Processor_Controller::GetClientDetail, processor, &Processor::GetClientDetail); 
    connect(processor, &Processor::GetDetailedFinished, this, &Processor_Controller::PassClientDetail); 
    processor_thread.start(); 

Und ich schaffe das QTcpServer im Hauptthread.

// The address of the server 
    QHostAddress srv_addr("127.0.0.1"); 

    // The server listen port 
    quint16 srv_port = 9895; 

    Processor_Controller *controller = new Processor_Controller(0, &server); 

    connect(&server, &QTcpServer::newConnection, controller, &Processor_Controller::BeginProcess); 

    connect(controller, &Processor_Controller::DisplayClientDetail, this, &MainWindow::DisplayClientDetail); 

    // BeginListen 
    if(!server.listen(srv_addr, srv_port)) 
     emit statusBar()->showMessage("Listen Failed"); 
    else 
     emit statusBar()->showMessage("Listen Success"); 

Die Funktion, die auf die GetSystemInfoOfClient Funktion aufrufen:

void Processor::GetClientDetail() 
{ 
    QString address = this->cli_addr.toString(); 
    QString port  = QString::number(this->cli_port); 
    QString SystemInfo = this->GetSystemInfoOfClient(); 
    emit this->GetDetailedFinished(address, port, SystemInfo); 
} 

Der Konstruktor der Prozessor:

Processor::Processor(QObject *parent, QTcpServer *server) : QObject(parent) 
{ 
    this->m_server = server; 
} 

Ich möchte nur einen Server im Hauptthread erstellen und verarbeiten die Verbindungen in der Prozessorklasse. Wie kann ich diesen Fehler vermeiden, ohne dieses Denken zu ändern?

+0

wenn Sie initialisieren 'cli_sock' Variable Versuch' Processor' Objekt einzustellen umschließt, wie es Eltern –

+0

ich hava ist versucht, das zu tun, aber Es machte keinen großen Unterschied – FancyBirds

+0

mehr Ideen zu spielen: 1) Erstellen Sie 'cli_addr' auf dem Heap, nicht auf dem Stapel 2) Zeigen Sie uns Code für' Prozessor' Konstruktor. Bei diesem Fehler handelt es sich um Thread-Affinität, d. H., Sie erstellen ein 'QObject' in einem Thread und verwenden in einem anderen –

Antwort

1

ich dieses Problem lösen gerade diese beiden Linie Codes in Processor::Accept Funktion

QTcpSocket *m_socket = m_server->nextPendingConnection(); 
this->cli_sock->setSocketDescriptor(m_socket->socketDescriptor(), m_socket->state(), m_socket->openMode()); 
+0

scheint verdächtig , aber danke für die Freigabe –

+0

werfen Sie einen Blick auf [Qt Threaded Fortune Server Beispiel] (http://doc.qt.io/qt-5/qtnetwork-threadedfortuneserver-example.html) und die Art, wie sie ein Multi-Thread implementieren Server und folgen Sie ihrem Muster. – Mike

+0

Siehe die Notiz am Ende von 'setSocketDescriptor's [Dokumentation] (http://doc.qt.io/qt-5/qabstractSocket.html#setSocketDescriptor), * Es ist nicht möglich, zwei abstrakte Sockets mit dem zu initialisieren gleicher nativer Socket-Deskriptor. *. In Ihrem Code verwenden Sie den gleichen Socket-Deskriptor in 'cli_sock' und' m_socket'. Sie werden bald oder später Probleme haben. . . – Mike