QT中解决QSocketNotifier: socket notifiers cannot be enabled from another thread错误
class UDPReceive : public QThread{ Q_OBJECTpublic: UDPReceive(); UDPReceive(QUdpSocket *s);protected: virtual void run();private: QUdpSocket *udp_socket; };UDPReceive::UDPReceive(){}UDPReceive::UDPReceive(QUdpSocket *s){ this->udp_socket = s;}void UDPReceive::run(){ while(1) { if (udp_socket->hasPendingDatagrams()) { if (udp_socket->pendingDatagramSize() >= rev_length) { ...... } } }}//在mainwindow中调用UDPReceivevoid MainWindow::init_socket(){ udp_socket = new QUdpSocket(this); udp_socket->bind(QHostAddress::Any, UDP_LISTEN_PORT, QUdpSocket::ReuseAddressHint); QHostAddress mcast_addr("224.0.0.17"); //udp_socket->setSocketOption(QAbstractSocket::MulticastLoopbackOption, 0);//禁止本机接收 udp_socket->joinMulticastGroup(mcast_addr); udp_receive = new UDPReceive(udp_socket); udp_receive->start();}
以上程序在运行时报QSocketNotifier: socket notifiers cannot be enabled from another thread错误。
到网上查了查,原因应该是,不能跨线程调用QObject。mainwindow为窗口主线程,UDPReceive为数据传输线程,所以当我们在mainwindow中创建udp_socket,然后通过指针的方式传递给UDPReceive使用,属于跨线程调用QObject。
解决办法为:将新建upd套接字的相关代码移到UDPReceive中,这样就避免了跨线程调用QObject。
void UDPReceive::run(){ QUdpSocket udp_socket; udp_socket.bind(QHostAddress::Any, this->udp_listen_port, QUdpSocket::ReuseAddressHint); QHostAddress mcast_addr("224.0.0.17"); udp_socket.setSocketOption(QAbstractSocket::MulticastLoopbackOption, 0);//禁止本机接收 udp_socket.joinMulticastGroup(mcast_addr); int rev_length = msg_max_length * 2 + 6; while(1) { if (udp_socket.hasPendingDatagrams()) { if (udp_socket.pendingDatagramSize() >= rev_length) { } } }}