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)
{
}
}
}
}