【发布时间】:2021-02-10 15:59:55
【问题描述】:
基本上我想实现一个简单而基本的设计。我有一个客户端套接字,它向套接字服务器发送和读取设置。为了避免在主线程中阻塞,整个套接字处理应该在不同的线程中完成。所以我创建了类MySocket:
MySocket.h(仅重要部分)
class MySocket : public QThread {
Q_OBJECT
public:
int port;
QHostAddress address;
bool running;
MySocket(QHostAddress addr, int port);
public slots:
void sendMessage(QByteArray data);
protected:
QTcpSocket* socket;
virtual void run();
signals:
void onDataReady(const QByteArray &data);
private slots:
void onReadyRead();
void newConnection();
void disconnected();
};
MySocket.cpp(仅重要部分)
#include "MySocket.h"
MySocket::MySocket(QHostAddress addr, int port) : port(port), address(addr), running(true)
{
}
void MySocket::onReadyRead()
{
QByteArray datas = socket->readAll();
//Send data to mainThread or somewhere else
emit onDataReady(datas);
}
void MySocket::run()
{
socket = new QTcpSocket();
QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
QObject::connect(socket,SIGNAL(connected()),this,SLOT(newConnection()));
QObject::connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()));
socket->connectToHost(address, port);
while(running)
{
QApplication::processEvents();
QThread::msleep(10);
}
}
void MySocket::sendMessage(QByteArray data){
qDebug()<< "writing Data ...";
if(socket->state() == QAbstractSocket::ConnectedState)
{
std::string message(data.constData(), data.length());
qDebug() << "SendingData: " << QString::fromStdString(message);
socket->write(data);
}
else{
qDebug() << "Socket not ready for writing";
}
}
主线程 (mainwindow.cpp) 只是创建并启动新线程。
mySocket = new MySocket(QHostAddress("127.0.0.1"), 3333);
controlSocket->start();
它还连接了用于写入的插槽和信号。
connect(this, SIGNAL(write(QByteArray)), mySocket, SLOT(sendMessage(QByteArray)));
每当我使用emit(write("some message")); 发出信号时,我都会收到以下错误/通知:
QSocketNotifier:不能从另一个线程启用或禁用套接字通知器
首先,我该如何解决这个问题?我创建了一个新线程,并且我还使用了许多其他面临类似问题的主题中提到的插槽/信号。套接字是否仍在发送这些消息?
【问题讨论】:
-
- 在 Qt 中,不需要将套接字放在线程中,因为一切都以非阻塞方式进行管理。 - 但是,如果您仍想这样做以平衡不同 CPU 上的负载,这是可能的。在这种情况下,我会在线程中读取数据并在读取数据时发出信号,以便与套接字相关的所有内容都在线程内。在您的连接中,“this”在主线程中! - 我认为你应该在线程中使用 QEventLoop 而不是 QApplication::processEvent。
-
@Alexandre:每当我想发送数据时都会收到警告(emit(write()) --> MySocket::sendMessage())。在这种情况下,“这个”真的是错误的吗?套接字实际上正在连接并调用 MySocket::newConnection。
标签: c++ multithreading qt sockets qt5