QT多线程 UdpSocket网络接收问题
问题描述:
一个接收网络数据的通道类,继承自QThread
头文件中相关内容
class QChannelRecv : public QThread
{
Q_OBJECT
public:
QUdpSocket *m_pUdpSocketDataRecv; // UdpSocket
int m_iPortData; // 数据端口
QHostAddress m_HAGroupAddress; //组播
QHostAddress m_HALocalAddress; //点对点
.
.
.
public slots:
void processRecvData(void);
void processRecvHeaderInfo(void);
}
源文件中相关内容
void QChannelRecv::run()
{
QString status;
if(m_pUdpSocketDataRecv != NULL)
{
m_pUdpSocketDataRecv->disconnect();
delete m_pUdpSocketDataRecv;
m_pUdpSocketDataRecv = NULL;
}
if(m_pUdpSocketDataRecv==NULL)
{
m_pUdpSocketDataRecv = new QUdpSocket();
m_HALocalAddress= QHostAddress(m_strCardIP);
if(!(m_pUdpSocketDataRecv->bind(m_HALocalAddress, m_iPortData, QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint)))
{
status = QString("因数据套接字绑定错误!退出%1接收线程");//.arg(m_strChannelName);
QMessageBox::critical(NULL,tr("Error"),status,QMessageBox::Yes);
return;
}
if(m_bMultiCast)//如果采用组播方式,加入组播地址
{
m_HAGroupAddress = QHostAddress(m_strGroupHostAddress);
m_pUdpSocketDataRecv->setSocketOption(QAbstractSocket::MulticastLoopbackOption,0);
m_pUdpSocketDataRecv->setSocketOption(QAbstractSocket::MulticastTtlOption,3);
if(!(m_pUdpSocketDataRecv->joinMulticastGroup(m_HAGroupAddress)))
{
status = QString("因数据套接字加入组播错误!退出%1接收线程").arg(m_strChannelName);
QMessageBox::critical(NULL,tr("Error"),status);
return;
}
}
connect(m_pUdpSocketDataRecv,SIGNAL(readyRead()),this,SLOT(processRecvData()),Qt::DirectConnection);
}
exec();
}
void QChannelRecv::processRecvData(void)
{
while (m_pUdpSocketDataRecv->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(m_pUdpSocketDataRecv->pendingDatagramSize());
m_pUdpSocketDataRecv->readDatagram(datagram.data(), datagram.size());
DisposeOriginData((unsigned char*)datagram.data(),datagram.size());
}
}
当第一次新建一个QChannelRecv *的对象 pChannelRecv后,调用pChannelRecv->start()
程序正常进入run()函数中,然后可以等待readyread()信号的发出,响应processRecvData(void)槽函数。可是当我执行其他操作,想要先把这个线程QThread关闭(exit()并且 delete pChannelRecv这个对象)后,再打开(pChannelRecv->start())意想不到的事情发生了,run()函数还是正常进入,可以槽函数processRecvData(void)没有得到响应。
然后我做了几次类似的操作,关闭本线程,再开启,其中有极少数的时候是可以进入这个processRecvData槽函数的。
上面都是点对点的发送,然后用组播时发现,这段程序可以顺利的执行。
请大家帮忙看看这里是什么原因造成这样的事情发生,该怎么处理呢?
一个接收网络数据的通道类,继承自QThread
头文件中相关内容
class QChannelRecv : public QThread
{
Q_OBJECT
public:
QUdpSocket *m_pUdpSocketDataRecv; // UdpSocket
int m_iPortData; // 数据端口
QHostAddress m_HAGroupAddress; //组播
QHostAddress m_HALocalAddress; //点对点
.
.
.
public slots:
void processRecvData(void);
void processRecvHeaderInfo(void);
}
源文件中相关内容
void QChannelRecv::run()
{
QString status;
if(m_pUdpSocketDataRecv != NULL)
{
m_pUdpSocketDataRecv->disconnect();
delete m_pUdpSocketDataRecv;
m_pUdpSocketDataRecv = NULL;
}
if(m_pUdpSocketDataRecv==NULL)
{
m_pUdpSocketDataRecv = new QUdpSocket();
m_HALocalAddress= QHostAddress(m_strCardIP);
if(!(m_pUdpSocketDataRecv->bind(m_HALocalAddress, m_iPortData, QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint)))
{
status = QString("因数据套接字绑定错误!退出%1接收线程");//.arg(m_strChannelName);
QMessageBox::critical(NULL,tr("Error"),status,QMessageBox::Yes);
return;
}
if(m_bMultiCast)//如果采用组播方式,加入组播地址
{
m_HAGroupAddress = QHostAddress(m_strGroupHostAddress);
m_pUdpSocketDataRecv->setSocketOption(QAbstractSocket::MulticastLoopbackOption,0);
m_pUdpSocketDataRecv->setSocketOption(QAbstractSocket::MulticastTtlOption,3);
if(!(m_pUdpSocketDataRecv->joinMulticastGroup(m_HAGroupAddress)))
{
status = QString("因数据套接字加入组播错误!退出%1接收线程").arg(m_strChannelName);
QMessageBox::critical(NULL,tr("Error"),status);
return;
}
}
connect(m_pUdpSocketDataRecv,SIGNAL(readyRead()),this,SLOT(processRecvData()),Qt::DirectConnection);
}
exec();
}
void QChannelRecv::processRecvData(void)
{
while (m_pUdpSocketDataRecv->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(m_pUdpSocketDataRecv->pendingDatagramSize());
m_pUdpSocketDataRecv->readDatagram(datagram.data(), datagram.size());
DisposeOriginData((unsigned char*)datagram.data(),datagram.size());
}
}
当第一次新建一个QChannelRecv *的对象 pChannelRecv后,调用pChannelRecv->start()
程序正常进入run()函数中,然后可以等待readyread()信号的发出,响应processRecvData(void)槽函数。可是当我执行其他操作,想要先把这个线程QThread关闭(exit()并且 delete pChannelRecv这个对象)后,再打开(pChannelRecv->start())意想不到的事情发生了,run()函数还是正常进入,可以槽函数processRecvData(void)没有得到响应。
然后我做了几次类似的操作,关闭本线程,再开启,其中有极少数的时候是可以进入这个processRecvData槽函数的。
上面都是点对点的发送,然后用组播时发现,这段程序可以顺利的执行。
请大家帮忙看看这里是什么原因造成这样的事情发生,该怎么处理呢?
...全文
相关推荐
使用qt 编写 udp 之间的对话
通过学习这些代码,开发者可以更好地理解和实践Qt中的UDP通信。实际应用中,你可能还需要考虑多线程、并发处理和数据包的序列化与反序列化等问题,以构建更复杂的UDP通信系统。
12.3.5 子线程创建UdpSocket实例
12.3.5子线程创建UdpSocket实例 实际开发中进行网络编程都会用到多线程,一般将数据接收代码放在子线程,主线程实现更新界面。下面编写的示例,是将UDP套接字相关代码放在子线程中,在子线程中完成了数据的接收;收到数据之后,通过信号传递给主线程,再更新显示到UI界面上。注意:本实例没有重写QThread类,是通过QObject::moveToThread函数将对象移动到新的线程中执行,这样可以解决主线程和子线程之间跨线程发送信号导致的一些错误问题。(配套代码CH12-8) 运行效果如下: .
Qt_UDP通信_qtudp_qtudp接收消息_qtudp接收文件_qtudp数据接收_qtudp接收
在实际应用中,还需要考虑错误处理、多线程、网络异常等问题,确保程序的稳定性和健壮性。
Qt UDP QUdpSocket多线程实例 movetothread
在实际项目中,可能还需要处理错误、添加日志记录、网络安全性等问题,但以上代码片段展示了基本的多线程UDP通信结构。
QT网络编程——UDP通信源码
});```在实际项目中,我们还需要考虑错误处理和多线程问题。


