QTcpSocket多线程遇到的读写数据问题
尝试用多线程使用QTcpSocket
在run()
方法中new QTcpSocket
;然后监听readyRead()
信号connect(m_pTcpSocket,SIGNAL(readyRead()),this,SLOT(sloat_RecvData()));
问题是当需要给服务器发送一段命令时(使用m_pTcpSocket->write(byteArray);
)程序会报出警告QSocketNotifier: socket notifiers cannot be enabled from another thread。
我在QThread
的子类WorkerThread
中使用QTcpSocket
来连接TCP服务器并给服务器发送数据。
主窗口代码
MyServer::MyServer(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);ui.port->setText("8899");setWindowTitle("服务器");//创建监听的服务器对象my_server = new QTcpServer(this);recv_worker = new RecvData;work_thread = new QThread;recv_worker->moveToThread(work_thread);connect(my_server, &QTcpServer::newConnection, this, [=]() {recv_worker->GetTcpSocket(my_server->nextPendingConnection());m_status->setPixmap(QPixmap(":/MyServer/connect.png").scaled(20, 20));});connect(recv_worker, &RecvData::recv_msg_signal, this, &MyServer::RecvMsg);connect(this, &MyServer::send_msg_signals, recv_worker, &RecvData::SendMsg);//状态栏m_status = new QLabel;m_status->setPixmap(QPixmap(":/MyServer/disconnect.png").scaled(20,20));ui.statusBar->addWidget(new QLabel("连接状态:"));ui.statusBar->addWidget(m_status);work_thread->start();
}
功能类
RecvData::RecvData(QObject *parent): QObject(parent)
{}RecvData::~RecvData()
{}void RecvData::GetTcpSocket(QTcpSocket* tcp)
{my_tcp = tcp;//检测是否可以接收数据connect(my_tcp, &QTcpSocket::readyRead, this, [=]() {QByteArray data = my_tcp->readAll();emit recv_msg_signal("客户端say:" + data);});connect(my_tcp, &QTcpSocket::disconnected, this, [=]() {my_tcp->close();my_tcp->deleteLater();emit socket_disconnected_signal();});//connect(my_tcp, &QTcpSocket::readyRead, this, &RecvData::RecvFile);
}
void RecvData::SendMsg(QString msg)
{my_tcp->write(msg.toUtf8());
}
可以连接到服务器,但是先调用write发送数据后,readyRead信号一直不进它的槽函数sloat_RecvData()
。表示这里发送失败了,客户端发不出数据了~
解决:
后来在使用完write()
方法后,再使用flush()
方法,就可以获取readyRead信号了。
qt的官方文档里说,调用了flush()
方法后,可以把缓冲的数据立刻发送出去。
估计QTcpSocket中的write()
方法是带有缓冲的,将接收部分阻塞了。
void RecvData::SendMsg(QString msg)
{my_tcp->write(msg.toUtf8());my_tcp->flush();
}