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试试吧。