当前位置:   article > 正文

基于Qt平台利用UDP协议传输大文件(百度网盘免费代码)_qt udp收发文件

qt udp收发文件

        UDP协议单次传输文件不能超过512字节,否则UDP数据包在IP曾需要拆分再重组,很容易出错。

        我们采取的办法是将需要传输的文件进行组包:服务器端组包,一个包由228字节的数据和28字节的包头组成,包头包含了数据的所有信息和客户端的接收方法。客户端从数据包中提取数据进行存储。

  百度网盘分享代码

        链接:https://pan.baidu.com/s/1cwcAH4ugobYqQ0c4UYdCiw 
        提取码:1234

        代码使用的注意事项:

        1.这个代码的UI没什么用处,因为对于发送端来说,对方的port是在代码指定的,只需要一个发送按钮就可以,接收方监听的端口也已经在代码指定。

        2.需要修改的地方:

        (1)服务器端代码:QFile file("D:\\3.ts");需要发送什么文件,就怎么写它的绝对路径。

        (2)客户端代码:把file.setFileName("3.ts")里的3.ts修改为你想保存的文件名和格式。

1.服务器端代码

  1. #include "server.h"
  2. #include "ui_server.h"
  3. #include <QTime>
  4. #include <QDesktopWidget>
  5. #include<QDebug>
  6. #include<QFileInfo>//获取文件信息
  7. server::server(QWidget *parent)
  8. : QMainWindow(parent)
  9. , ui(new Ui::server)
  10. {
  11. ui->setupUi(this);
  12. m_udpSocket = new QUdpSocket(this);
  13. sendsize=0;
  14. m_udpSocket->setSocketOption(QAbstractSocket::SendBufferSizeSocketOption,8*1024*1024);
  15. m_udpSocket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption,500000);
  16. }
  17. server::~server()
  18. {
  19. delete ui;
  20. }
  21. void server::on_pushButton_clicked()
  22. {
  23. //while(1) {
  24. // QPixmap result = QPixmap();
  25. // result = QPixmap::grabWindow(QApplication::desktop()->winId(), 0, 0, 800, 600); //抓取当前屏幕的图片
  26. // result.save("D:\\LX\\Work\\Project\\802PC\\TcpServetTest\\802TCPServer\\eee.jpg");
  27. QFile file("D:\\3.ts");
  28. if (!file.open(QIODevice::ReadOnly))return;
  29. //1024=包头28(7个整形)+数据(996
  30. char *m_sendBuf = new char[1024];
  31. //size:文件大小
  32. int size = file.size();
  33. qDebug()<<"文件大小"<<size;
  34. //num:数据包数量
  35. int num = 0;
  36. //count:数据包序号
  37. int count = 0;
  38. //最后一个包的大小
  39. int endSize = size%996;
  40. if (endSize == 0) {
  41. num = size/996;
  42. }
  43. else {
  44. num = size/996+1;//num:包的数量
  45. }
  46. qint64 len = 0;//记录发送数据
  47. // //一、发送文件信息
  48. // //1.获取文件路径
  49. // QString filepath = "D:/3.ts";
  50. // //2.获取文件信息
  51. // QFileInfo info(filepath);
  52. // fileName = info.fileName();
  53. // fileSize = info.size();
  54. // //3.设置文件名
  55. // file.setFileName(filepath);
  56. //二、发送数据
  57. //1、组包:28字节包头+996字节数据
  58. //2、发送:广播到port:65522
  59. while (count < num) {
  60. //初始化:将m_sendBuf的前1024个字符置0
  61. memset(m_sendBuf, 0, 1024);
  62. //包的结构体
  63. ImageFrameHead mes;
  64. //功能码24
  65. mes.funCode = 24;
  66. //包头长度=4*7=28
  67. mes.uTransFrameHdrSize = sizeof(ImageFrameHead);
  68. if ((count+1) != num) {
  69. //数据长度
  70. mes.uTransFrameSize = 996;
  71. }
  72. else {
  73. //最后一个包的长度
  74. mes.uTransFrameSize = endSize;
  75. }
  76. //qDebug()<<size;
  77. //数据帧总大小=文件大小
  78. mes.uDataFrameSize = size;
  79. //包个数
  80. mes.uDataFrameTotal = num;
  81. //包序号
  82. mes.uDataFrameCurr = count+1;
  83. //数据996的整数倍
  84. mes.uDataInFrameOffset = count*(1024 - sizeof(ImageFrameHead));
  85. qDebug()<<"uDataInFrameOffset"<<mes.uDataInFrameOffset;
  86. //读取文件,参数1:存储位置——指针,参数2:maxsize
  87. //参数1:意思是指向m_sendBuf向后移28位的位置,将996位的数据存在这里
  88. //从文件里读取996字节数据写入m_sendBuf数据包里数据的位置
  89. // data:file(996字节)->m_sendBuf(29字节起-1024字节)
  90. len = file.read(m_sendBuf+sizeof(ImageFrameHead), 1024-sizeof(ImageFrameHead));
  91. sendsize+=len;
  92. qDebug()<<"已发送文件大小"<<sendsize;
  93. //从mes里复制28个字节给m_sendBuf,mes:包头结构体。
  94. //构建包:m_sendBuf的前28字节写包的信息。
  95. memcpy(m_sendBuf, (char *)&mes, sizeof(ImageFrameHead));
  96. //发数据:m_sendBuf即包。
  97. //参数2:包的长度=表头+数据=1024,最后一个包不一定
  98. m_udpSocket->writeDatagram(m_sendBuf, mes.uTransFrameSize+mes.uTransFrameHdrSize, QHostAddress("224.0.0.10"), 65522);
  99. //currentTime:返回当前时间
  100. //addMSecs:返回QTime对象dieTime,其时间比当前时间延后1ms
  101. //dieTime = 当前时间 + 1ms
  102. QTime dieTime = QTime::currentTime().addMSecs(1);
  103. //防止卡死,隔一段时间检查有没有未完成操作
  104. while( QTime::currentTime() < dieTime )
  105. QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
  106. count++;
  107. }
  108. qDebug()<<"数据发送完成";
  109. file.close();
  110. QTime dieTime = QTime::currentTime().addMSecs(10);
  111. while( QTime::currentTime() < dieTime )
  112. QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
  113. //qDebug("ok");
  114. }
  115. //}

 2.客户端代码

  1. #include "client.h"
  2. #include "ui_client.h"
  3. client::client(QWidget *parent)
  4. : QMainWindow(parent)
  5. , ui(new Ui::client)
  6. {
  7. ui->setupUi(this);
  8. m_udpThread = new UdpThread(this);
  9. //sigRecvok:线程完成——读取结束的信号
  10. //信号传来了数据char
  11. connect(m_udpThread, SIGNAL(sigRecvOk(char*,int)), this, SLOT(slotRecv_client(char*,int)));
  12. m_udpThread->start();
  13. qDebug("OK");
  14. }
  15. client::~client()
  16. {
  17. delete ui;
  18. }
  19. void client::slotRecv_client(char * buf, int len)
  20. {
  21. file.setFileName("3.ts");
  22. filesize = len;
  23. file.resize(filesize);
  24. bool isOK = file.open(QIODevice::WriteOnly);//isOK:文件成功打开标志
  25. qDebug()<<isOK;
  26. qint64 write_len=file.write(buf,len);
  27. qDebug()<<"client:写入文件的大小"<<write_len;
  28. qDebug()<<"filesize="<<len;
  29. QPixmap pixmap;
  30. pixmap.loadFromData((uchar*)buf, len, "ts");
  31. ui->label->setPixmap(pixmap);
  32. file.close();
  33. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/305236?site
推荐阅读
相关标签
  

闽ICP备14008679号