我们往往使用tcp协议传输数据,都会自定义一个包裹,本次分享下对包的理解,其基本结构如下:
在发送端,我们只需要将完整的包裹一次发送出去即可,eg
// 字节
QByteArray bytes;
PackageInfo info;
info.exUse_int = 1000;
info.exUse_char = '1';
// bodyLen 非定长
info.dataSize = buffer.size();
QDataStream stream(&bytes,QIODevice::WriteOnly);
// head
stream << info.exUse_int << info.exUse_char << info.dataSize;
// body
bytes.append(buffer.data());
socket->write(bytes);
接受时,由于发送端告知发送的数据总字节数,以及body字节数,所以我们可以在接受端判断接收,直到完整接收。
if(bytesAvailable() <= 0)
{
return;
}
// 总缓存,每次不满就存入,清空问题待处理
static QByteArray bytes;
// head,定长
const static int headLen = sizeof(unsigned int) + sizeof(unsigned char) + sizeof(qint64);
QByteArray t_bytes = readAll();
bytes.append(t_bytes);
if(bytes.size() < headLen)
{
// 继续缓存
return;
}
// head已经完整get,获取真实数据长度
PackageInfo info;
QDataStream stream(&bytes, QIODevice::ReadOnly);
stream >> info.exUse_int >> info.exUse_char >> info.dataSize;
// 读满
if(bytes.size() < info.dataSize + headLen)
{
// 继续缓存
return;
}
// bodyData
QByteArray dataBytes = bytes.right(bytes.size() - headLen);
// to do
我们一次发送很大的包裹,接收时是多次的,因为,像tcp这种水龙头流水,你用杯子接水,至于你接了多少水不可控。因此我们使用静态变量存储,或者成员变量,每次填充到缓存中并比较要接收的大小,直到完整get即可。这里就是告诉客户端,你需要接收多大,一个完整的包裹。
关于Tcp协议,粘包问题,等仍需要处理。至于涉及的高并发等深入问题仍需要学习。