客户端解析广播数据
/***************************************************************************************************************************************************************
数据包格式:
文本数据包格式: 群聊标志 + 发信息员工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个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
宝塔面板允许jar文件,报这个错,大佬救一下[流泪]
7
用户中心项目求问
4
#提问#小程序文档也太乱了吧!想问一下我在去年5月注册了一个微信小程序企业号,今年会过期吗?过期后我上线的小程序岂不是寄了?毕设要用,担心5月过期赶不上答辩
0
#求职# 求助 请问一下大家,星球有那种关于秋招企业投递汇总的表不[机智]
6
鱼神,想咨询一下目前Java的现状,先介绍一下我自身的情况吧本人是本科毕业一年,农学专业,在学校就对编程有兴趣,但是没时间去学校,现在迫切想转行去学Java,想了解一下目前的Java的就业咋样,现在就是在上班,但是工作自身干起来也很不顺心,一直想学习Java这块,就是在想报班好一些还是自学好一些,学成之后的出路怎么样,希望鱼神能给为小弟指点迷津
7
