Qt:解决跨线程调用socket/IO类,导致报错的问题

Qt有很多IO相关的类,比如说QTcpSocket、QFile,总的来说,在Qt的框架内使用,还是非常方便的。
但是用过其他框架IO类的人,可能有一个很不习惯,就是Qt的所有IO类,都不推荐或者不可以跨线程操作,不然就会报错,比如说操作QTcpSocket跨线程调用write接口,就会报错:
 

socket notifiers cannot be enabled from another thread

要解决这个问题,直观的说就是不要跨线程操作,网上也有很多类似的说明。
这也是有道理的,很多时候真的是设计问题导致的,因为设计失误出现了不应该有的跨线程操作。
当然也可以用信号和槽封装一下,但是这样会涉及很多不必要的代码,我个人觉得也太过于麻烦。
那么我这里就提供一个更简单的方法,对QTcpSocket跨线程调用代码如下:
 

QMetaObject::invokeMethod( &socket, std::bind( static_cast< qint64(QTcpSocket::*)(const QByteArray &) >( &QTcpSocket::write ), &socket, QByteArray( "xxxx" ) ) );

 

Qt:解决跨线程调用socket/IO类,导致报错的问题(socket notifiers cannot be enabled from another thread)_qt 异步线程调用io-CSDN博客

Qt是一种现代化的C++应用程序开发框架,它提供了许多功能强大和易于使用的库,QtSocket库用于实现网络通信、传输数据等功能。QtSocket库在应用中发挥了非常重要的作用,特别是在session服务器的开发中,由于该服务器需要同时处理多个客户端的请求,所以使用多线程技术能够让服务器更加高效的处理请求。 具体实现Qt Socket线程session服务器代码可以使用QThread来实现多线程QThreadQt中专门用于处理线程,可以创建多个线程,并且可以通过信号和槽机制来实现线程通信。对于session服务器,可以每当一个客户端连接到服务器,使用QThread创建一个新的线程来处理该客户端的请求。在每个线程中,我们可以使用QTcpSocket来处理客户端的请求,并且使用信号和槽机制来实现线程间的通信。 下面是一个简单的Qt Socket线程session服务器代码的示例: ```cpp class SessionThread : public QThread { Q_OBJECT public: SessionThread(qintptr socketDescriptor); signals: void error(QTcpSocket::SocketError socketError); protected: void run() override; private: QTcpSocket *m_tcpSocket; qintptr m_socketDescriptor; }; class SessionServer : public QTcpServer { Q_OBJECT public: SessionServer(QObject *parent = nullptr); void startServer(); protected: void incomingConnection(qintptr socketDescriptor) override; signals: void newConnection(qintptr socketDescriptor); }; SessionThread::SessionThread(qintptr socketDescriptor) : m_socketDescriptor(socketDescriptor) { } void SessionThread::run() { m_tcpSocket = new QTcpSocket(); if (!m_tcpSocket->setSocketDescriptor(m_socketDescriptor)) { emit error(m_tcpSocket->error()); return; } connect(m_tcpSocket, &QTcpSocket::readyRead, this, [this]() { QByteArray request = m_tcpSocket->readAll(); // handle request m_tcpSocket->write("processed request"); }); connect(m_tcpSocket, &QTcpSocket::disconnected, m_tcpSocket, &QTcpSocket::deleteLater); exec(); } SessionServer::SessionServer(QObject *parent) : QTcpServer(parent) { } void SessionServer::startServer() { if (!listen(QHostAddress::LocalHost, 5555)) { qDebug() << "error: " << errorString(); } else { qDebug() << "server started"; } } void SessionServer::incomingConnection(qintptr socketDescriptor) { emit newConnection(socketDescriptor); SessionThread *thread = new SessionThread(socketDescriptor); connect(thread, &SessionThread::finished, thread, &SessionThread::deleteLater); connect(thread, &SessionThread::error, this, [thread](QTcpSocket::SocketError error) { qDebug() << "error: " << error; thread->quit(); }); thread->start(); } ``` 在上面的代码中,`Session_server`是一个派生自`QTcpServer`的,用于创建一个TCP服务器。在这个中实现了`incomingConnection()`函数,该函数在客户端开始连接时被调用,该函数中我们可以通过创建一个新的线程来处理客户端的请求。在每个线程中,我们可以使用QTcpSocket来处理客户端请求,在线程中实现处理请求和发送回应过程。`\ 使用QTsocket开发线程session服务器代码时,需要特别注意线程间的同步问题,确保每个线程的请求能够被正确的处理、及时的响应客户端请求。同时,在请求响应过程中,需要考虑到服务端的性能问题,精细地设计线程和网络IO操作等细节,保证高效运行和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值