QT中解决QSocketNotifier: socket notifiers cannot be enabled from another thread错误

class UDPReceive : public QThread
{
    Q_OBJECT
public:
    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中调用UDPReceive
void 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)
            {
            }
        }
    }
} 

你可能感兴趣的:(QT编程)