想用UDP组播传输数据,但是数据量大,大概90~200W字节,一次,因为qt的udp套接字最大能发送数据的长度为:
65535- IP头(20) - UDP头(8)=65507字节,所以进行拆包处理,将整包数据包分为固定大小,然后for循环发送,但是无论拆多大
,如果循环发送都会报错unalbe to send a message。
以下为模拟数据代码
QList<TestStruct> tmpLst;
TestStruct tmpTest;//这里产生大量数据
for(int i = 0;i<ui->spinBox->value();i++)
{
tmpTestm_Test1.nID =i;
tmpTest.m_Test2.nID =i;
tmpLst.append(tmpTest);
}
if(tmpLst.size() == 0)
{
return;
}
int nData = tmpLst.size()*sizeof (TestStruct);
int ntmpCount = 1;
if(ui->checkBox_startWhile->isChecked())
{
ntmpCount = ui->spinBox_count->value();
}
//===============================================================================================
char* pDataTBuf = new char[nData];
for(int i = 0;i<ntmpCount;i++)
{
TestStruct tmpInfo;
for(int i = 0;i<tmpLst.size();i++)
{
tmpInfo = tmpLst.at(i);
memcpy(pDataTBuf + i*sizeof (TestStruct),&tmpInfo,sizeof (TestStruct));
}
//这里产生大量数据,数据发送给UDP套接字管理对象
if(m_pChannel)
{
m_pChannel->sendUdpData(20005,pDataTBuf,nData);
}
}
delete []pDataTBuf;
pDataTBuf = nullptr;
下面是组包过程
void CUdpComm::parseSendData(const SendDataInfo &array)
{
//通过队列取出刚刚存储的数据
const char* pTmpBuf = array.dataArray.data();
const int nTmpDataLen = array.dataArray.size();
if(nTmpDataLen < m_nPacketSize)//m_nPacketSize为每一包大小
{
int nHeadLen = sizeof(FrameHead);//帧头
FrameHead tmpFrame;
tmpFrame.nID = array.nDataType;//20005
tmpFrame.sFlag = 0xFFFF;
tmpFrame.sDataLength = nHeadLen + nTmpDataLen;
tmpFrame.nPacketCount = 1;
tmpFrame.nPacketSort = 0;
tmpFrame.llTime = QDateTime::currentMSecsSinceEpoch();
char* pTBuf = new char[tmpFrame.sDataLength];
memcpy(pTBuf,&tmpFrame,nHeadLen);
memcpy(pTBuf + nHeadLen,pTmpBuf,nTmpDataLen);
//线程中,发出信号,然后再槽函数发送数据
emit signalSendData( tmpFrame.nID,QByteArray(pTBuf,tmpFrame.sDataLength));
delete []pTBuf;
pTBuf = nullptr;
}
else
{
int nHeadLen = sizeof(FrameHead);
const char* pBufPos = pTmpBuf;
short nPacketCount = (nTmpDataLen % m_nPacketSize?nTmpDataLen/m_nPacketSize+1:nTmpDataLen/m_nPacketSize);//判断包个数
int nTestDataLen = 0;//用于记录发送的数据长度,不包含头,后面和nTmpDataLen比较是否一致
for(int i = 0;i<nPacketCount;i++)
{
FrameHead tmpFrame;
tmpFrame.nID = array.nDataType;;//20005
tmpFrame.sFlag = 0XFFFF;
if(i == nPacketCount -1)
{
tmpFrame.sDataLength = nHeadLen + (nTmpDataLen -(i) * m_nPacketSize);
}
else
{
tmpFrame.sDataLength = nHeadLen + m_nPacketSize;
}
tmpFrame.nPacketSort = i;
tmpFrame.nPacketCount = nPacketCount;
tmpFrame.llTime = QDateTime::currentMSecsSinceEpoch();
char* pTBuf = new char[tmpFrame.sDataLength];
memcpy(pTBuf,&tmpFrame,nHeadLen);//添加帧头
memcpy(pTBuf + nHeadLen,pBufPos,tmpFrame.sDataLength - nHeadLen);//添加数据
nTestDataLen += tmpFrame.sDataLength - nHeadLen;
pBufPos = pBufPos + tmpFrame.sDataLength - nHeadLen;
// QThread::msleep(5);//发太快会有问题,所以停一下,没有太大作用
emit signalSendData(tmpFrame.nID,QByteArray(pTBuf,tmpFrame.sDataLength));
delete []pTBuf;
pTBuf = nullptr;
}
}
}
最终发送函数
qint64 nWriteLen = m_pUdpSender->writeDatagram(pBuf,nDataLen,"224.0.0.123",12345);
如果过快,最终会报错 unable to send a message,有相关经验的还请指点一下,像这种需要传大量数据的情况怎么处理?