第一步:定义TCP包的头head(单解包视频)
uint m_head;//定义通信需要的协议包头
QByteArray m_head_buffer;
m_head = 0xffff; m_head_buffer.append(m_head>>24).append(m_head>>16).append(m_head>>8).append(m_head);//将m_head分成“8个比特位”的4个char型的数据储存在m_head_buffer中
第二步:
QTcpSocket *m_tcp_socket;//接收到数据的套接字
connect(m_tcp_socket, &QTcpSocket::readyRead, this, [=](){
//将m_tcp_socket中的信息储存到recv_data
QByteArray recv_data = m_tcp_socket->readAll();
if(recv_data.isNull()) return; //recv_data没有收到套接字m_tcp_socket的信息,直接返回退出
//recv_data收到了套接字m_tcp_socket的信息,将其储存到m_temp_buffer中
m_temp_buffer.append(recv_data);
//m_temp_buffer的size小于8,说明一个头都没收全.自定义TCP头为8,前四位为0xffff,后四位为数据包的大小
if(m_temp_buffer.size() <=8) return;
int index = m_temp_buffer.indexOf(m_head_buffer);//判断m_head_buffer在m_temp_buffer中的哪一个位置
if(index == -1)
{
m_temp_buffer.clear(); return;
}
while(index != -1)
{
//优化m_temp_buffer储存的数据
//将m_temp_buffer的第一个头(m_head_buffer)放到m_temp_buffer的首地址中
m_temp_buffer = m_temp_buffer.mid(index);
//判断头是否完整(不完整),截取完了之后还够不够8个字节
//注意有两个判断-》if(m_temp_buffer.size() <= 8)
//第一个是判断收到的数据够不够8个字节
//第二个是判断mid()函数截取后够不够8个字节
if(m_temp_buffer.size() <= 8)
return;
//判断头完整(且有数据)
else{
uint buffer_size = 0;//准备储存TCP中head包含的后面数据大小的信息
//m_temp_buffer.data()返回m_temp_buffer的首地址head的,前四位是0xffff,后四位是包的大小
memcpy(&buffer_size, m_temp_buffer.data() + 4, 4);
//数据包长度不足一帧
if((uint)m_temp_buffer.size() < buffer_size + 8)
return;
else{
QByteArray frame_buffer = m_temp_buffer.mid(8, buffer_size);
m_temp_buffer = m_temp_buffer.mid(buffer_size + 8);
this->PurseTcpVidioData(frame_buffer);//解析TCP数据
}
}
index = m_temp_buffer.indexOf(m_head_buffer);
}
});
第一步:定义TCP包的头head(同时解视频包和文本包的防粘包处理)
uint m_head;//定义通信需要的协议包头
QByteArray m_head_buffer;
m_head = 0xffff; m_head_buffer.append(m_head>>24).append(m_head>>16).append(m_head>>8).append(m_head);//将m_head分成“8个比特位”的4个char型的数据储存在m_head_buffer中
flag位标志位,flag=1,发送的包为视频包;flag=0,发送的包为文本包;等等类推
第二步:
QTcpSocket *m_tcp_socket;//接收到数据的套接字,开始解包操作
connect(m_tcp_socket, &QTcpSocket::readyRead, this, [=](){
QByteArray recv_data = m_tcp_socket->readAll();
if(recv_data.isNull()) return;
m_temp_buffer.append(recv_data);
if(m_temp_buffer.size() <= 12) return;
//判断m_head_buffer在m_temp_buffer中的哪一个位置
int index = m_temp_buffer.indexOf(m_head_buffer);
if(index == -1)
{
m_temp_buffer.clear(); return;
}
while(index != -1)
{
//优化m_temp_buffer储存的数据
//将m_temp_buffer的第一个头(m_head_buffer)放到m_temp_buffer的首地址中
m_temp_buffer = m_temp_buffer.mid(index);
//判断头是否完整(不完整)????
if(m_temp_buffer.size() <= 12)
return;
else//判断头完整(且有数据)
{
uint buffer_size = 0;//准备储存TCP中head包含的后面数据大小的信息
//m_temp_buffer.data()返回m_temp_buffer的首地址head的,前四位是0xffff,后四位是包的大小
memcpy(&buffer_size, m_temp_buffer.data() + 4, 4);
uint type_date = 0;
memcpy(&type_date, m_temp_buffer.data() + 8, 4);
//数据包长度不足一帧
if((uint)m_temp_buffer.size() < buffer_size + 12)
return;
else
{
if(type_date==1){//这一步判断是解视频包
QByteArray frame_buffer = m_temp_buffer.mid(12, buffer_size);
m_temp_buffer = m_temp_buffer.mid(buffer_size + 12);
this->PurseTcpVidioData(frame_buffer);//解析TCP数据
}
else{//这一步判断是解文本包
QByteArray txt_buffer = m_temp_buffer.mid(12, buffer_size);
m_temp_buffer = m_temp_buffer.mid(buffer_size + 12);
qDebug()<<txt_buffer;//解析TCP数据
qDebug()<<"txt_buffer的大小"<<txt_buffer.size();
if(txt_buffer=="\x10")
AudioWaining();
}
}
}
index = m_temp_buffer.indexOf(m_head_buffer);
}
});