2016-05-13 14 views
0

vorbei habe ich versucht, wie in Verbindung 1. Youtube tutorial to create multithreaded serverInformationen über Threaded tcpserver von einem Thread zu einem anderen

void Test_Server::incomingConnection(int socketDescriptor_) 
{ 
    qDebug() << socketDescriptor_ << "connecting..."; 
    Test_Thread *thread_ = new Test_Thread(number_,socketDescriptor_,this); 
    connect(thread_,SIGNAL(finished()),thread_,SLOT(deleteLater())); 
    thread_->start(); 
    number_++; 
} 

////

void Test_Thread::run() 
{ 
    qDebug() << this->Socket_Descriptor_ << "starting thread"; 
    socket = new QTcpSocket(); 
    if(!socket->setSocketDescriptor(Socket_Descriptor_)) 
    { 
     qDebug() << "ERROR"; 
    } 
    connect(socket,SIGNAL(readyRead()),this,SLOT(Ready_read_()),Qt::DirectConnection); 
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected_()),Qt::DirectConnection); 
    qDebug() << this->Socket_Descriptor_ << "Client connected"; 
    QByteArray name = QByteArray::number(number_); 
    server_->Socket_map_.insert(name,this); 
    server_->show_all_connected_sockets_(); 
    exec(); 
} 

Mein Ziel einfachen Server zu erstellen, ist beides miteinander zu verbinden Clients zum Server (ich benutze Telnet), schreiben von Client 1 auf Server etwas, und Server sollte Daten an Client 2 übergeben. Um dies zu tun, habe ich QMap Speicher Zeiger auf MyThreads gemacht. Wenn Daten von Client 1 empfangen wird, ich rufe Methode:

void Test_Server::write_to_client_(int number, QByteArray data) 
{ 
QByteArray name = QByteArray::number(number); 
    Test_Thread *pointer; 
    pointer = client_socket_(name); 
    connect(this,SIGNAL(send_data_(QByteArray)),pointer,SLOT(write_data_(QByteArray))); 
    emit send_data_(data); 
    disconnect(this,SIGNAL(send_data_(QByteArray)),pointer,SLOT(write_data_(QByteArray))); 
    qDebug() << "void Test_Server::write_to_client_(int number, QByteArray data): data sent"; 
} 

////

void Test_Thread::write_data_(QByteArray data) const 
{ 
    socket->write(data); 
    socket->waitForBytesWritten(); 
} 

vorbei allgemeinen Informationen funktioniert, schreibe ich in Client 1 einige Daten und 2-Client zeigt es , aber ich werde geting:

TQObject: Kann Kinder für einen Elternteil nicht herstellen, der in einem anderen Thread ist.

Übergeordneter Test_Thread ist QNativeSocketEngine (Zeiger 1), Elternthread ist> (Zeiger 2), aktueller Thread ist (Zeiger 3);

QsocketNotifier: Socket-Notifier können nicht von einem anderen Thread aus aktiviert oder deaktiviert werden.

Meine Frage ist: Wie übertrage ich Daten von Client 1, zu Server und dann zu Client 2? Ich habe Forschung betrieben und das Problem liegt in der richtigen Verwendung von Signalen und Slots, aber ich kann nicht herausfinden, wie ich das richtig machen soll.

+0

Ich bin nicht sicher, ob der betreffende Teil des Codes (die eine, die den Fehler macht) ist in dem Code, den Sie gepostet haben. – perencia

+0

@perencia in 'Test_Server :: write_to_client_ (int-Nummer, QByteArray-Daten)' Es gab eine Menge von qDebug() Lanes mit Informationen, ich habe Fehler nach dem Aussenden eines Signals erhalten. write_data_ SLOT ist implementiert mit 2-spurigem Code, socket-> write (data); und socket-> waitforBytesWritten(); – proton

+0

Ich würde sagen, das Problem ist, dass der Socket im Haupt-Thread erstellt wird und Sie versuchen, seinen QSocketNotifier für den zweiten Thread zu verwenden, der eine andere Ereignisschleife hat. Wie kommt 'Socket' zu Test_Thread? Übergeben Sie es vom Hauptthread? – perencia

Antwort

0

Ich endlich Problem gelöst. Um das zu tun i gefolgt ähnliche Frage hier beschriebene Lösung: PROBLEM & SOLUTION Ich habe resigniert Klasse MyThread zu verwenden, stattdessen erstellte Klasse Worker und zog es wie hier unten einzufädeln:

void Test_Server::incomingConnection(int socketDescriptor_) 
{ 
    qDebug() << "void Test_Server::incomingConnection current thread: " << QThread::currentThread(); 
    qDebug() << socketDescriptor_ << "connecting..."; 
    Socket_map_.insert(number_,QByteArray::number(socketDescriptor_)); 
    QThread *thread_= new QThread; 
    qDebug() << "void Test_Server::incomingConnection new thread_: " << thread_->thread(); 
    Test_Worker *worker = new Test_Worker(socketDescriptor_); 
    worker->moveToThread(thread_); 
    connect(thread_,SIGNAL(started()),worker,SLOT(create_socket_())); 
    connect(this,SIGNAL(pass_socket_descriptor_(int)),worker,SLOT(set_socket_descriptor_(int))); 
    connect(worker,SIGNAL(finished()),thread_,SLOT(quit())); 
    connect(worker,SIGNAL(finished()),worker,SLOT(deleteLater())); 
    connect(thread_,SIGNAL(finished()),thread_,SLOT(deleteLater())); 
    connect(worker,SIGNAL(pass_data_to_server_(QByteArray,QByteArray)),this,SLOT(data_from_socket_(QByteArray,QByteArray))); 
    connect(this,SIGNAL(pass_data_to_client_(QByteArray,QByteArray)),worker,SLOT(show_data_received_from_server_(QByteArray,QByteArray))); 
    number_++; 
    thread_->start(); 
} 

TIPP: Wenn ich Socket erstellt über test_server Signal create_socket_ (int) und Socket create_socket (int), Programm hat nicht richtig funktioniert. Um dies zu beheben das Signal vom Start-Thread-Buchse anschließen - create_socket_

Programm jetzt succesfuly ohne Fehler empfangen Daten von Client 1 und übergeben es an Client 2.

0

Test_Thread::write_data ist nicht auf dem gleichen Thread ausgeführt wird, wo die Buchse angelegt wurde, ist, dass Test_Thread::run(). In der Klasse QThread läuft nur, was auf der run-Methode ausgeführt wird, auf einem separaten Thread.

+0

also, was Sie vorschlagen, um dieses Problem zu lösen? – proton

+0

Wenn Sie 'socket-> waitForBytesWritten() kommentieren,' erhalten Sie den Fehler? – perencia

+0

nein, aber ohne 'socket-> waitForBytesWritten();' manchmal zeigt der Server zwei separate Daten an. – proton

Verwandte Themen