tcp业务层数据包分片

QString msgType="MSG_ID_ALREADY_EXIST";
QByteArray block;
QDataStream out(&block,QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_6);
out<<(quint16)0<<msgType;
out.device()->seek(0);
out<<(quint16)(block.size()-sizeof(quint16));
tcpSocket->write(block);


QByteArray 查了,叫字节数组,
QDataStream说是提供二进制数据到QIOdevice的串行化,
QIODevice是输入输出的基类
串行化是:将对象存储到介质中或是以二进制方式通过网络传输


使用out<<(quint16) 0,在block的开始添加了一个quint16大小的空间,也就是两字节的空间,它用于后面放置文件的大小信息。然后out<<msgType输入实际的文件,这里是字符串"MSG_ID_ALREADY_EXIST"

。当文件输入完成后我们在使用out.device()->seek(0);返回到block的开始,加入实际的文件大小信息,也就是后面的代码,它是实际文件的大小:out<<(quint16) (block.size() – sizeof(quint16));


[code=C/C++][/code] QString msgType="MSG_ID_ALREADY_EXIST"; //这句不解释
  QByteArray block; //不解释
  QDataStream out(&block,QIODevice::WriteOnly); //这一句相当于拿QByteArray对象来进行加工也就是你所谓的串行化
  out.setVersion(QDataStream::Qt_4_6); //这一句是设置数据串行化所使用的版本
  out<<(quint16)0<<msgType; //这里其实要分成两部分看前面的0只是用来占空间的,后面才是真正要发送的数据
  out.device()->seek(0);//你可以理解为吧流定位到开始的位置,这个位置是刚才用数字0来进行填充的空间
  out<<(quint16)(block.size()-sizeof(quint16));//这里是计算出真正要发送的数据大小,把这个计算后的值填入之前提前占好的空间中
  tcpSocket->write(block);//发送TCP数据
1.TCP数据是一串长长的流,你事先不知道它的长度
  2.因此你需要现用一个东西来占用TCP流最开始的那段空间

  3.当加入真正要发送的数据的时候,流的大小才能确定下来,这个时候就吧计算好的结果放到之前占的那个空间去


out.setVersion(QDataStream::Qt_4_6);
  //设置数据流的版本,客户端和服务器端使用的版本要相同

block.size包括两部分:文件大小信息(2字节)+文件实际大小(msgType的长度),你说的没错。

我们都在数据流的最开始写入完整文件的大小信息,这样接收端就可以根据大小信息来判断是否接受到了完整的文件。



阅读更多
个人分类: QT学习
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭