首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > QT开发 >

QT TCP通信服务器出错,该怎么处理

2013-12-21 
QT TCP通信服务器出错本帖最后由 ggyanjiang 于 2013-12-16 22:12:05 编辑服务器端在接收到客户端的消息之

QT TCP通信服务器出错
本帖最后由 ggyanjiang 于 2013-12-16 22:12:05 编辑 服务器端在接收到客户端的消息之后就提示QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0xa7e6428), parent's thread is mythread(0x35ea30), current thread is QThread(0x3578b0)

//widget.cpp
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    server = new mytcpserver;
    listen();
}

void Widget::listen()
{
    if(server->listen(QHostAddress::Any,5555))
    {
        ui->status_label->setText("listening");
    }
    else
    {
        qDebug() << server->errorString();
        close();
    }
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_clear_pushButton_clicked()
{
    ui->listWidget->clear();
}

//mytcpserver.cpp
#include "mytcpserver.h"
#include "mythread.h"

mytcpserver::mytcpserver(QObject *parent) :
    QTcpServer(parent)
{
}

void mytcpserver::incomingConnection(int socketDescriptor)
{
    mythread *thread = new mythread(socketDescriptor,this);
    connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));
    thread->start();
}

//mythread.cpp
#include "mythread.h"

mythread::mythread(int socketDcriptor,QObject *parent) :
    QThread(parent),socket_fd(socketDcriptor)
{
}

void mythread::run()
{
    server_socket = new QTcpSocket;    //不要在主线程中创建,即不要加上this
    server_socket->setSocketDescriptor(socket_fd);
    connect(server_socket,SIGNAL(readyRead()),this,SLOT(readMessage()));
    exec();        //这样会显示的调用消息循环进而触发slot
}

void mythread::readMessage()
{
    QByteArray block = server_socket->readAll();
    QDataStream in(&block,QIODevice::ReadOnly);
    in.setVersion(QDataStream::Qt_4_6);
    QString readmsg;
    quint16 blockSize = 0;
    in >> blockSize >> readmsg;
    qDebug() << tr("server receive a message:") << readmsg;
    sendMessage();
}

void mythread::sendMessage()
{
    QString msg = "server received sucess";
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_6);
    out << (quint16)0;
    out << msg;
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));
    server_socket->write(block);
    //server_socket->disconnectFromHost();
    //server_socket->waitForDisconnected();
}


[解决办法]
如果你能把listen放到mythread里面就不会有这样的问题.
或者 把incomingConnection放到mythread里面,但是这个我不确定有效.
总之就是建立socket和接收消息都在一个线程里面就不会出错.
至于为什么,我也不太说得清楚.还就是qtcp没有必要多线程.
如果你想多线程,可以在收到消息之后在线程里面抛出信号...本人理解不是很到位.仅供参考下.
[解决办法]
你在run中connect的信号和槽函数采用的是默认的AutoConnection,这样槽函数会在它所在的线程中执行,而你的_socket是在线程的run中初始化的,槽函数中无法直接调用。把连接方式改成DirectConnection试试吧。

热点排行