客户端解析广播数据



/***************************************************************************************************************************************************************

数据包格式:
文本数据包格式: 群聊标志 + 发信息员工QQ号 + 收信息员工QQ号(群QQ号)+ 信息类型(1) + 数据长度 + 数据
表情数据包格式:群聊标志 + 发信息员工QQ号 + 收信息员工QQ号 (群QQ号) + 信息类型(0) + 表情个数+images+表情名称
文件数据包格式:群聊标志 + 发信息员工QQ号 + 收信息员工QQ号 (群QQ号) + 信息类型(2) + 文件字节数 + bytes + 文件名 + data_begin + 文件数据

群聊标志占1位,0表示单聊,1表示群聊
信息类型占1位,0表示表情信息,1表示文本信息,2表示文件信息

QQ号占5位 ,群QQ号占4位,数据长度占5位,表情名称占3位
(注意:当群聊标志为1时,则数据包没有收信息员工QQ号,而是收信息群QQ号
当群聊标志为0时,则数据包没有收信息群QQ号,而是收信息员工QQ号)

群聊文本信息如: 1100012001100005Hello 表示QQ10001向群2001发送文本信息,长度是5,数据为Hello
单聊图片信息如: 0100011000201images060 表示QQ10001向QQ10002发送一个表情60.png
群聊文件信息如: 1100052000210bytestest.txtdata_beginhelloworld
表示QQ10005向群2000发送文本信息,文件是test.txt,文件内容长度10,内容helloworld


群聊文件信息解析: 1 10001 2001 1 00005 Hello
单聊图片信息解析: 0 10001 10002 0 060
群聊文件信息解析: 1 10005 2000 2 10 bytes test.txt data_begin helloworld
**************************************************************************************************************************************************************/
void TalkWindowShell::processPendingData()
{
//端口中有未处理的数据
while (m_udpReceiver->hasPendingDatagrams())
{
const static int groupFlagWidth = 1; //群聊标志占位
const static int groupWidth = 4; //群QQ号宽度
const static int employeeWidth = 5; //员工QQ号宽度
const static int msgTypeWidth = 1; //信息类型宽度
const static int msgLengthWidth = 5; //文本信息长度的宽度
const static int pictureWidth = 3; //表情图片的宽度


//读取udp数据
QByteArray btData;
btData.resize(m_udpReceiver->pendingDatagramSize());
m_udpReceiver->readDatagram(btData.data(),btData.size());

QString strData = btData.data();
QString strWindowID;//聊天窗口ID,群聊则是群号,单聊则是员工QQ号
QString strSendEmployeeID, strRecevieEmployeeID;//发送及接收端的QQ
QString strMsg; //数据


int msgLen; //数据长度
int msgType; //数据类型

strSendEmployeeID = strData.mid(groupFlagWidth, employeeWidth);

//自己发的信息不做处理
if (strSendEmployeeID == gLoginEmployeeID)
{
return;
}

if (btData[0] == '1')//群聊
{
strWindowID = strData.mid(groupFlagWidth + employeeWidth,groupFlagWidth);

QChar cMsgType = btData[groupFlagWidth + employeeWidth + groupWidth];

if (cMsgType == '1')//文本信息
{
msgType = 1;
msgLen = strData.mid(groupFlagWidth + employeeWidth + groupWidth + msgTypeWidth,msgLengthWidth).toInt();
strMsg = strData.mid(groupFlagWidth + employeeWidth + groupWidth + msgType + msgLengthWidth,msgLen);

}
else if (cMsgType == '0')//表情信息
{
msgType = 0;
int posImages = strData.indexOf("images");
strMsg = strData.right(strData.length() - posImages - QString("images").length());
}
else if (cMsgType == '2')//文件信息
{
msgType = 2;
int bytesWidth = QString("bytes").length();
int posBytes = strData.indexOf("bytes");
int posData_begin = strData.indexOf("data_begin");

//文件名称
QString fileName = strData.mid(posBytes + bytesWidth ,posData_begin - posBytes - bytesWidth);
gfileName = fileName;

//文件内容
int dataLengthWidth;
int posData = posData_begin + QString("data_begin").length();
strMsg = strData.mid(posData);
gfileData = strMsg;

//根据employeeID获取发送者姓名
QString sender;
int employeeID = strSendEmployeeID.toInt();
QSqlQuery queryGroupName(QString("SELECT employee_name FROM tab_employees WHERE employeeID = %1")
.arg(employeeID));
queryGroupName.exec();

if (queryGroupName.first())
{
sender = queryGroupName.value(0).toString();
}

//接收文件的后续操作。。。
ReceiveFile *recvFile = new ReceiveFile(this);
connect(recvFile, &ReceiveFile::refuseFile, [this]() {
return;
});
QString msgLabel = QString::fromLocal8Bit("收到来自") + sender +
QString::fromLocal8Bit("发来的文件,是否接收?");
recvFile->setMsg(msgLabel);
recvFile->show();
}
}
else //单聊
{
strRecevieEmployeeID = strData.mid(groupFlagWidth + employeeWidth,employeeWidth);
strWindowID = strSendEmployeeID;

// 不是发给我的信息不做处理
if (strRecevieEmployeeID != gLoginEmployeeID)
{
return;
}

//获取信息的类型
QChar cMsgType = btData[groupFlagWidth + employeeWidth + employeeWidth];
if (cMsgType == '1')//文本信息
{
msgType = 1;

//文本信息长度
msgLen = strData.mid(groupFlagWidth + employeeWidth + employeeWidth
+ msgTypeWidth,msgLengthWidth).toInt();

//文本信息
strMsg = strData.mid(groupFlagWidth + employeeWidth + employeeWidth
+ msgTypeWidth + msgLengthWidth,msgLen);
}
else if (cMsgType == '0')//表情信息
{
msgType = 0;
int posImages = strData.indexOf("images");
int imagesWidth = QString("images").length();
strMsg = strData.mid(posImages + imagesWidth);
}
else if(cMsgType == '2')//文件信息
{
msgType = 2;

int bytesWidth = QString("bytes").length();
int posBytes = strData.indexOf("bytes");
int data_beginWidth = QString("data_begin").length();
int posData_begin = strData.indexOf("data_begin");

//文件名称
QString fileName = strData.mid(posBytes + bytesWidth,posData_begin - posBytes - bytesWidth);
gfileName = fileName;

//文件内容
strMsg = strData.mid(posData_begin + data_beginWidth);
gfileData = strMsg;


//根据employeeID获取发送者姓名
QString sender;
int employeeID = strSendEmployeeID.toInt();
QSqlQuery queryGroupName(QString("SELECT employee_name FROM tab_employees WHERE employeeID = %1")
.arg(employeeID));
queryGroupName.exec();

if (queryGroupName.first())
{
sender = queryGroupName.value(0).toString();
}
//接收文件的后续操作。。。
ReceiveFile *recvFile = new ReceiveFile(this);
connect(recvFile, &ReceiveFile::refuseFile, [this]() {
return;
});

QString msgLabel = QString::fromLocal8Bit("收到来自") + sender +
QString::fromLocal8Bit("发来的文件,是否接收?");
recvFile->setMsg(msgLabel);
recvFile->show();
}
}

//将聊天窗口设为活动窗口
QWidget* widget = WindowManager::getInstance()->findWindowName(strWindowID);
if (widget)//聊天窗口存在
{
this->setCurrentWidget(widget);

//同步激活左侧聊天窗口
QListWidgetItem* item = m_talkwindowItemMap.key(widget);
item->setSelected(true);
}
else//聊天窗口未打开
{
return;
}

//文件信息另作处理
if (msgType != 2)
{
int sendEmployeeID = strSendEmployeeID.toInt();
handleReceivedMsg(sendEmployeeID, msgType, strMsg);
}
}
}


0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
鱼友5897
下载 APP