【问题标题】:passing information on Threaded TcpServer from one thread to another将有关 Threaded TcpServer 的信息从一个线程传递到另一个线程
【发布时间】:2016-09-09 23:34:40
【问题描述】:

我尝试像链接 1 那样创建简单的服务器。 Youtube tutorial to create multithreaded server

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();
}

我的目标是将两个客户端连接到服务器(我使用 telnet),从客户端 1 向服务器写入内容,服务器应该将数据传递给客户端 2。 为此,我制作了 QMap 来存储指向 MyThreads 的指针。当从客户端 1 收到数据时,我正在调用方法:

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();
}

通常传递信息有效,我在客户端 1 中写入一些数据,客户端 2 显示它,但是我得到了:

TQObject:无法为不同的父级创建子级 线程。

父Test_Thread是QNativeSocketEngine(Pointer 1),父线程是>(Pointer 2),当前线程是(Pointer 3);

QsocketNotifier:不能从另一个线程启用或禁用套接字通知器。

我的问题是:如何正确地将数据从客户端 1 传递到服务器,然后再传递到客户端 2?我已经进行了研究,问题在于正确使用信号和插槽,但我不知道如何以正确的方式进行。

【问题讨论】:

  • 我不确定代码的相关部分(导致错误的部分)是否在您发布的代码中。
  • @perencia in 'Test_Server::write_to_client_(int number, QByteArray data)' 有很多带有信息的 qDebug() 通道,我在发出信号后收到错误。 write_data_SLOT 是用 2 lane 代码实现的,socket->write(data);和 socket->waitforBytesWritten();
  • 我想说的问题是套接字是在主线程中创建的,而您正试图在第二个线程上使用它的 QSocketNotifier,它具有不同的事件循环。 socket 如何到达 Test_Thread ?你是从主线程传递的吗?
  • @perencia 在 Server::incomingConnection 中创建线程,然后在线程启动后,在 Thread::run() 中创建套接字。我已将 Thread::run() 的代码添加到 question
  • 我和你差不多有same problem,你能帮我看看吗?

标签: c++ multithreading qt tcp server


【解决方案1】:

我终于解决了问题。为此,我遵循了此处描述的类似问题解决方案:PROBLEM & SOLUTION 我已经辞职使用 MyThread 类,而是创建了 Worker 类并将其移至如下线程:

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();
}

提示:当我通过 test_server 信号创建套接字时 create_socket_(int) 和socket create_socket(int),程序不能正常工作。修理 将信号从启动线程连接到套接字 - create_socket_

程序现在成功地从客户端 1 接收数据并将其传递给客户端 2。

【讨论】:

    【解决方案2】:

    Test_Thread::write_data 不在创建套接字的同一线程上运行,即Test_Thread::run()。在QThread 类中,只有在run 方法上运行的内容才能在单独的线程上运行。

    【讨论】:

    • 如果你评论socket-&gt;waitForBytesWritten();你会得到错误吗?
    • 否,但如果没有socket-&gt;waitForBytesWritten();,有时服务器会显示附加了 2 个单独的数据。
    猜你喜欢
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多