Qt中使用UDP的方式传送图片

1.首先将图片转换成QByteArray

QPixmap pixmap = QPixmap::fromImage(image);
QByteArray bytes;
QBuffer buff(&bytes);
buff.open(QIODevice::ReadWrite);
pixmap.save(&buff, "JPG");

2.定义数据包包头结构体

struct ImageFrameHead {
 
    unsigned int funCode;               //功能码,用于区分数据包中的内容
    unsigned int uTransFrameHdrSize;    //sizeof(ImageFrameHead),数据包头的大小
    unsigned int uTransFrameSize;       //Data Size,数据包中数据的大小
    //数据帧变量
    unsigned int uDataFrameSize;        //图片数据总大小
    unsigned int uDataFrameTotal;       //图片数据被分数据帧个数
    unsigned int uDataFrameCurr;        //数据帧当前的帧号
    unsigned int uDataInFrameOffset;    //数据帧在整帧的偏移
};

3.划分图片数据,按照每帧1024个字节划分

#define DATA_FRAME_SIZE 1024
QByteArray sendBuff;
sendBuff.resize(DATA_FRAME_SIZE);
int size = buff.size();
int num = 0;
int count = 0;
int endSize = size%(DATA_FRAME_SIZE - sizeof(ImageFrameHead));
if (endSize == 0)
{
    num = size/(DATA_FRAME_SIZE - sizeof(ImageFrameHead));
}
else
{
    num = size/(DATA_FRAME_SIZE - sizeof(ImageFrameHead)) + 1;
}
while (count < num)
{
    memset(sendBuff.data(), 0, 1024);
    ImageFrameHead head;
    head.funCode = XchatVideo;
    head.uTransFrameHdrSize = sizeof(ImageFrameHead);
    if ((count+1) != num) {
        head.uTransFrameSize = DATA_FRAME_SIZE - sizeof(ImageFrameHead);
    }
    else {
        head.uTransFrameSize = endSize;
    }
    head.uDataFrameSize = size;
    head.uDataFrameTotal = num;
    head.uDataFrameCurr = count+1;
    head.uDataInFrameOffset = count*(DATA_FRAME_SIZE - sizeof(ImageFrameHead));
    memcpy(sendBuff.data()+sizeof(ImageFrameHead), (bytes.data()+head.uDataInFrameOffset), DATA_FRAME_SIZE - sizeof(ImageFrameHead));
    memcpy(sendBuff.data(), (char *)&head, sizeof(ImageFrameHead));
    //使用udp将sendbuff发送到指定地址
    sendData(sendBuff);
    count++;
}
 
 

4.接收端接收到符合条件的数据后,将数据拼包,直到组成完整数据之后,将数据转换成QImage.

QByteArray recvBuf;
char* m_buf = new char[1024*1024];
 
while(m_udpSocket->hasPendingDatagrams())
{
    int size = m_udpSocket->pendingDatagramSize();
    recvBuf.resize(size);
 
    m_udpSocket->readDatagram(recvBuf.data(), size);
 
    unsigned int head = 0;
    memcpy(&head, recvBuf.data(), sizeof(unsigned int));
 
    if(head == XchatVideo)
    {
        ImageFrameHead *imgHead = (ImageFrameHead *)recvBuf.data();
        memcpy(m_buf + (imgHead->uDataInFrameOffset), (recvBuf.data()+ sizeof(ImageFrameHead)), imgHead->uTransFrameSize);
 
        if (imgHead->uDataFrameCurr == imgHead->uDataFrameTotal)
        {
            QByteArray data;
            data.resize(imgHead->uDataFrameSize);
            memcpy(data.data(), m_buf, imgHead->uDataFrameSize);
 
            QImage image;
            image.loadFromData(data,"JPG");
            QPixmap pixmap = QPixmap::fromImage(image);
        }
    }
}
 
delete m_buf;


  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
QUdpSocket 是 C++ Qt 框架的一个类,用于实现 UDP(User Datagram Protocol)套接字通信。UDP 是一种无连接的、不可靠的传输协议,适用于对数据传输延迟要求较低、可容忍丢失或乱序的场景。 QUdpSocket 类提供了发送和接收 UDP 数据报的方法,并支持多主机之间的通信。它可以在客户端和服务器之间进行双向通信,也可以用于广播和多播的应用。 可以使用 QUdpSocket 类的实例来创建一个 UDP 套接字,并通过调用相应的函数来发送和接收数据报。常用的函数包括 bind() 绑定本地地址和端口、readDatagram() 读取数据报、writeDatagram() 发送数据报等。 以下是一个使用 QUdpSocket 类实现简单 UDP 通信的示例代码: ```cpp #include <QtNetwork> int main() { // 创建 QUdpSocket 对象 QUdpSocket udpSocket; // 绑定本地地址和端口 udpSocket.bind(QHostAddress::LocalHost, 12345); // 发送数据报 QByteArray datagram = "Hello, World!"; udpSocket.writeDatagram(datagram, QHostAddress::LocalHost, 6789); // 接收数据报 while (udpSocket.hasPendingDatagrams()) { QByteArray receivedDatagram; receivedDatagram.resize(udpSocket.pendingDatagramSize()); udpSocket.readDatagram(receivedDatagram.data(), receivedDatagram.size()); qDebug() << "Received datagram:" << receivedDatagram; } return 0; } ``` 以上代码创建了一个 UDP 套接字对象 udpSocket,并将其绑定到本地地址和端口 12345。然后使用 writeDatagram() 函数发送数据报给本地地址和端口 6789。接下来使用 readDatagram() 函数接收数据报,并打印在控制台上。 这只是一个简单的示例,QUdpSocket 类还提供了许多其他功能和函数,可以根据需求进行更复杂的 UDP 通信实现。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值