打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Qt模块化笔记之network——第二个TCP程序,传输图片文件的实现(2)

本节你将了解如何传输一个文件,以图片文件示例。

在以前socket的write函数只,我们都只是写入少量的文字,大小也许还不到一K,它的写入时间极短,接收时间也极短,很少需要考虑是否保证它完整地传输到另一端。

但文件不同,文件的传输需要保证它的每一部分都传送到另一端,另一端才能将它还原。

比如我们的浏览器从网络下载文件的时候,它在下载之前就获得了需要下载的文件信息,如文件名,文件大小,进而在本地硬盘创建文件,将内容写入。从而实现下载。知道文件大小,还可以通过已接收到的字节数量,计算下载百分比。

为保证我们的文件完整地传送到另一端,我们需要让另一端先知道文件的大小等基本信息。这就需要叫做“文件头”的部分。文件头是文件的一些相关信息。

看下面发送图片的实例:

  1. QBuffer buffer;  
  2. QByteArray dataStr;  
  3. QDataStream out( &dataStr,QIODevice::WriteOnly );  
  4. out.setVersion(QDataStream::Qt_5_2);  
  5. buffer.open(QIODevice::ReadWrite);  
  6. img.save(&buffer,"PNG");  
  7. out << qint32(buffer.size())<<QString(fileName)<< buffer.data();  
  8. Socket->write(dataStr);  

img是QImage,这个类是专门用于IO的,如果直接传输QPixmap,将破坏图片内部的信息,如分辨率等,导致在另一端无法将图片还原。上面代码将图片保存到buffer中,通过dataStream将它存入QByteArray dataStr,最后用tcp socket写入dataStr。

out << qint32(buffer.size())<<QString(fileName)<< buffer.data();这一句中需要qint32等进行“修饰”,是因为,qint32代表32-bit即四个字节,表示的数字范围大小足够用了。QString也类似,不去查了,假设它2个字节。<< qint32(buffer.size())<<QString(fileName)就是传输文件头了。 buffer.data()传输数据内容。

这样,我们的数据可想像为,格式:aaaabbccccccc……。读取时,只要顺序读出来不就行了吗?

最后,图片在500K左右,我们一次性发送出去。


接收时:

  1. connect(clientSocket,SIGNAL(readyRead()),this,SLOT(readData()));  
  2.   
  3. void Client::readData()  
  4. {  
  5. QDataStream in( clientSocket );  
  6. in.setVersion(QDataStream::Qt_5_2);  
  7. if( dataSize == 0 )//dataSize是一个自己设的qint32  
  8. {  
  9.    if( clientSocket->bytesAvailable() < (sizeof(quint32)+sizeof(QString)) )  
  10.    {  
  11.         return;  
  12.    }  
  13.    in >> dataSize;//按顺序读出。先入先出顺序  
  14.    in>>fileName;//<span style="font-family: Arial, Helvetica, sans-serif;">fileName是设的QString</span>  
  15. }  
  16. if( dataSize > qint32(clientSocket->bytesAvailable()))//图片比较小,让它存在clientSocket的缓存中,直到大小满足关系,即文件内容都传输完毕后才读取出来。  
  17. {  
  18.    return;  
  19. }  
  20. QByteArray a;  
  21. in>>a;  
  22. img.loadFromData(a);//这个就是存进去的QImage了  
  23.   
  24. dataSize=0;//重置为0,等待下一次传输  
  25. }  



如果文件极大。比如几百M,几个G的,就不能用上述方法了。

这时,需要不断地用IO类如QFile,从源文件中read一定数量的字节,然后循环发出。接收时也要比较大小。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
(转)4.3加载和保存(LoadingandSaving)
Linux socket编程(五) 文件传输
Qt 文件处理
C# TCP 客户端代码
在QT中使用TCP协议进行文件传输(可以单向循环传输)
四十八、Qt网络(八)TCP(二)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服