Qt通过UDP传图片,实现自定义分包和组包
来源:互联网 发布:silverlight调用js 编辑:程序博客网 时间:2024/05/17 14:19
转载 http://blog.csdn.net/caoshangpa/article/details/52681572
一.包头结构体
- //包头
- struct PackageHeader
- {
- //包头大小(sizeof(PackageHeader))
- unsigned int uTransPackageHdrSize;
- //当前包头的大小(sizeof(PackageHeader)+当前数据包长度)
- unsigned int uTransPackageSize;
- //数据的总大小
- unsigned int uDataSize;
- //数据被分成包的个数
- unsigned int uDataPackageNum;
- //数据包当前的帧号
- unsigned int uDataPackageCurrIndex;
- //数据包在整个数据中的偏移
- unsigned int uDataPackageOffset;
- };
为何要分包可参考:TCP、UDP数据包大小的限制
二.分包与组包
1.分包
- int dataLength=buffer.data().size();
- unsigned char *dataBuffer=(unsigned char *)buffer.data().data();
- int packetNum = 0;
- int lastPaketSize = 0;
- packetNum = dataLength / UDP_MAX_SIZE;
- lastPaketSize = dataLength % UDP_MAX_SIZE;
- int currentPacketIndex = 0;
- if (lastPaketSize != 0)
- {
- packetNum = packetNum + 1;
- }
- PackageHeader packageHead;
- packageHead.uTransPackageHdrSize=sizeof(packageHead);
- packageHead.uDataSize = dataLength;
- packageHead.uDataPackageNum = packetNum;
- unsigned char frameBuffer[1024*1000];
- memset(frameBuffer,0,1024*1000);
- while (currentPacketIndex < packetNum)
- {
- if (currentPacketIndex < (packetNum-1))
- {
- packageHead.uTransPackageSize = sizeof(PackageHeader)+UDP_MAX_SIZE;
- packageHead.uDataPackageCurrIndex = currentPacketIndex+1;
- packageHead.uDataPackageOffset = currentPacketIndex*UDP_MAX_SIZE;
- memcpy(frameBuffer, &packageHead, sizeof(PackageHeader));
- memcpy(frameBuffer+sizeof(PackageHeader), dataBuffer+packageHead.uDataPackageOffset, UDP_MAX_SIZE);
- int length=udpsocketSend->writeDatagram(
- (const char*)frameBuffer, packageHead.uTransPackageSize,
- QHostAddress(ui->lineEditIP->text()), ui->lineEditPort->text().toInt());
- if(length!=packageHead.uTransPackageSize)
- {
- qDebug()<<"Failed to send image";
- }
- currentPacketIndex++;
- }
- else
- {
- packageHead.uTransPackageSize = sizeof(PackageHeader)+(dataLength-currentPacketIndex*UDP_MAX_SIZE);
- packageHead.uDataPackageCurrIndex = currentPacketIndex+1;
- packageHead.uDataPackageOffset = currentPacketIndex*UDP_MAX_SIZE;
- memcpy(frameBuffer, &packageHead, sizeof(PackageHeader));
- memcpy(frameBuffer+sizeof(PackageHeader), dataBuffer+packageHead.uDataPackageOffset, dataLength-currentPacketIndex*UDP_MAX_SIZE);
- int length=udpsocketSend->writeDatagram(
- (const char*)frameBuffer, packageHead.uTransPackageSize,
- QHostAddress(ui->lineEditIP->text()), ui->lineEditPort->text().toInt());
- if(length!=packageHead.uTransPackageSize)
- {
- qDebug()<<"Failed to send image";
- }
- currentPacketIndex++;
- }
- }
2.组包
- static int num = 1;
- static uint size = 0;
- PackageHeader *packageHead = (PackageHeader *)datagram.data();
- if (packageHead->uDataPackageCurrIndex == num)
- {
- num++;
- size += packageHead->uTransPackageSize-packageHead->uTransPackageHdrSize;
- if (size > 1024*1000)
- {
- qDebug()<<"image too big";
- num = 1;
- size = 0;
- return;
- }
- if (packageHead->uDataPackageOffset > 1024*1000)
- {
- qDebug()<<"image too big";
- packageHead->uDataPackageOffset = 0;
- num = 1;
- size = 0;
- return;
- }
- memcpy(imageData.data+packageHead->uDataPackageOffset, datagram.data()+packageHead->uTransPackageHdrSize,
- packageHead->uTransPackageSize-packageHead->uTransPackageHdrSize);
- if ((packageHead->uDataPackageNum == packageHead->uDataPackageCurrIndex)
- && (size == packageHead->uDataSize))
- {
- imageData.length = packageHead->uDataSize;
- QImage image;
- image.loadFromData((uchar *)imageData.data,imageData.length,"JPG");
- QPixmap pixmap=QPixmap::fromImage(image);
- ui->labelImage_2->setPixmap(pixmap);
- recvImageNum++;
- ui->lineEditRevFrame->setText(QString::number(recvImageNum));
- ui->lineEditRevSize->setText(QString::number(imageData.length));
- memset(&imageData,0,sizeof(UdpUnpackData));
- num = 1;
- size = 0;
- }
- }
- else
- {
- num = 1;
- size = 0;
- memset(&imageData,0,sizeof(UdpUnpackData));
- }
三.示例
界面包括发送端和接收端,接收端的IP地址是自动获取的本机IP地址,上图将发送端的IP地址设置为与接收端IP地址相同,可实现自发自收。
每秒帧数可实时设置每秒发送图片的张数,发送帧数表示一共发送了多少张,接收帧数表示一共接收了多少张,图片大小表示每张图片多少Byte。
可将示例运行于两台计算机,实现双向收发。
源码链接:见http://blog.csdn.net/caoshangpa/article/details/52681572的评论
- 顶
- 4
- 踩
- 0
- 上一篇Qt调用jrtplib实现单播、多播和广播
- 下一篇Qt之窗口动画(下坠、抖动、透明度)
相关文章推荐
- • Qt总结
- • [分享]比较全的电脑网络基础知识
- • Windows系统及应用技巧二十六篇
- • 网管教程+从入门到精通软件篇
- • Windows系统及应用技巧二十六篇
- • Qt中如何利用 png 图片来实现自定义形状的窗口
- • qt利用委托:QStyledItemDelegate,实现tableview 的表格项的自定义显示,如插入图片,绘制控件
- • Qt自定义委托在QTableView中绘制控件、图片、文字
阅读全文
0 0
- Qt通过UDP传图片,实现自定义分包和组包
- Qt通过UDP传图片,实现自定义分包和组包
- 【转】C#实现UDP分包组包
- 【转】C#实现UDP数据包大文件分包传输和接收组包
- UDP分包组包的类
- 关于socket 分包和组包
- H264分包组包
- 一个UDP包的固定分包丢包问题
- 简析H264分包组包
- 处理粘包和半包有关问题的socket分包Java实现
- Socket粘包,分包解决方法和算法
- TCP的粘包和分包
- scoket如何处理粘包和分包
- 通过自定义View实现圆形图片
- 分包图片
- Qt-----实现Udp通信
- UDP分包重组算法和 基于RTP的H264视频数据分包重组
- UDP分包重组算法
- Java学习轨迹【面向对象(2)】
- 转动的风扇
- 内部类
- 位运算
- 设计模式遵循的六大基本原则
- Qt通过UDP传图片,实现自定义分包和组包
- C语言单链表面试题1
- golang实践-如何优先使用通道替换锁
- VR系列——Oculus Rift 开发者指南:四、高级渲染配置(五)
- socket接口转换操作(网络序与主机序)
- Javascript实现简单的下拉菜单
- 汽车运动演示
- Android禁止输入表情符号
- iOS 视频压缩、音视频混合、音频混合