Qt 下 UDP 丢包解决方案 + TCP 粘包完美解决方案

目录

[一、TCP 粘包(Qt 最标准解法:固定包头 + 包体)](#一、TCP 粘包(Qt 最标准解法:固定包头 + 包体))

什么是粘包?

[Qt 解决方案(工业 99% 用这个)](#Qt 解决方案(工业 99% 用这个))

[✅ Qt TCP 粘包解决完整代码](#✅ Qt TCP 粘包解决完整代码)

[1. 发送端(加包头)](#1. 发送端(加包头))

[2. 接收端(自动拆包,永不粘包)](#2. 接收端(自动拆包,永不粘包))

[二、UDP 丢包(Qt 5 种实用解决方案)](#二、UDP 丢包(Qt 5 种实用解决方案))

[✅ 方案 1:应用层 ACK + 超时重传(最常用,最有效)](#✅ 方案 1:应用层 ACK + 超时重传(最常用,最有效))

原理

[Qt 实现代码](#Qt 实现代码)

[✅ 方案 2:增加序列号 + 丢包重传请求(可靠 UDP)](#✅ 方案 2:增加序列号 + 丢包重传请求(可靠 UDP))

[✅ 方案 3:降低发送速率 + 分包发送(简单有效)](#✅ 方案 3:降低发送速率 + 分包发送(简单有效))

[✅ 方案 4:FEC 前向纠错(视频 / 语音专用)](#✅ 方案 4:FEC 前向纠错(视频 / 语音专用))

[✅ 方案 5:心跳 + 重连机制](#✅ 方案 5:心跳 + 重连机制)

[三、最终总结(Qt 开发必背)](#三、最终总结(Qt 开发必背))

[TCP 粘包解决](#TCP 粘包解决)

[UDP 丢包解决](#UDP 丢包解决)

[Qt 完整工程:TCP (包头分包防粘包)+ 可靠 UDP (ACK + 超时重传防丢包)](#Qt 完整工程:TCP (包头分包防粘包)+ 可靠 UDP (ACK + 超时重传防丢包))

[一、工程 pro (共用)](#一、工程 pro (共用))

[模块 1:TCP 固定 4 字节大端包头,彻底解决粘包 / 半包](#模块 1:TCP 固定 4 字节大端包头,彻底解决粘包 / 半包)

tcpcommon.h (公用打包解包)

tcpserver.h

tcpserver.cpp

tcpclient.h

tcpclient.cpp

[模块 2:可靠 UDP(序号 + ACK+300ms 超时重传,解决丢包)](#模块 2:可靠 UDP(序号 + ACK+300ms 超时重传,解决丢包))

udpcommon.h

udpserver.h

udpserver.cpp

udpclient.h

udpclient.cpp

[main.cpp 测试入口](#main.cpp 测试入口)

二、关键原理说明

[TCP 防粘包要点](#TCP 防粘包要点)

[UDP 防丢包三层保障](#UDP 防丢包三层保障)

三、扩展优化 (按需添加)

[Qt 可靠 UDP 心跳 + 自动重连 完整可运行代码](#Qt 可靠 UDP 心跳 + 自动重连 完整可运行代码)

核心原理(一句话)

完整代码(直接复制用)

[1. 全局定义(udpheartbeat.h)](#1. 全局定义(udpheartbeat.h))

[2. 客户端代码(带心跳 + 重连)](#2. 客户端代码(带心跳 + 重连))

udpclient.h

udpclient.cpp

[3. 服务端代码(应答心跳)](#3. 服务端代码(应答心跳))

udpserver.h

udpserver.cpp

[4. 测试 main.cpp](#4. 测试 main.cpp)

这个机制到底解决了什么?

[✔ 心跳机制](#✔ 心跳机制)

[✔ 超时判断](#✔ 超时判断)

[✔ 自动重连](#✔ 自动重连)

[✔ 可靠 UDP 基础](#✔ 可靠 UDP 基础)

大白话总结


Qt 下 UDP 丢包解决方案 + TCP 粘包完美解决方案

全程 Qt 原生代码 + 原理 + 示例,不讲废话,直接能用!


一、TCP 粘包(Qt 最标准解法:固定包头 + 包体)

什么是粘包?

TCP 是流数据,多条数据会连在一起,接收端分不清从哪里开始、哪里结束。

Qt 解决方案(工业 99% 用这个)

发送:4 字节长度 + 数据体 接收:先读 4 字节长度 → 再读对应长度数据


✅ Qt TCP 粘包解决完整代码

1. 发送端(加包头)

cpp

运行

复制代码
void sendTcpData(QTcpSocket *socket, const QByteArray &data)
{
    if (!socket || socket->state() != QAbstractSocket::ConnectedState)
        return;

    // 第一步:构造 4字节包头(存储数据长度) + 数据体
    QByteArray sendBuf;
    QDataStream stream(&sendBuf, QIODevice::WriteOnly);
    stream.setByteOrder(QDataStream::BigEndian);

    // 写入数据长度(4字节)
    stream << (quint32)data.size();
    // 写入真实数据
    sendBuf.append(data);

    socket->write(sendBuf);
}

2. 接收端(自动拆包,永不粘包)

cpp

运行

复制代码
// 成员变量
QByteArray m_tcpBuffer;   // 接收缓冲区

void onTcpReadyRead()
{
    QTcpSocket *socket = (QTcpSocket*)sender();
    m_tcpBuffer.append(socket->readAll()); // 追加数据

    // 循环拆包(解决粘包 + 半包)
    while (true)
    {
        // 1. 不够4字节 → 包头都没收完
        if (m_tcpBuffer.size() < 4)
            break;

        // 2. 读取数据长度
        quint32 dataLen;
        QDataStream stream(m_tcpBuffer);
        stream.setByteOrder(QDataStream::BigEndian);
        stream >> dataLen;

        // 3. 缓冲区不够一包数据 → 等待
        if (m_tcpBuffer.size() < 4 + dataLen)
            break;

        // 4. 拆出完整一包
        QByteArray onePack = m_tcpBuffer.mid(4, dataLen);
        
        // 处理你的数据 onePack
        parseOnePackage(onePack);

        // 移除已处理数据
        m_tcpBuffer = m_tcpBuffer.mid(4 + dataLen);
    }
}

二、UDP 丢包(Qt 5 种实用解决方案)

UDP 不保证送达,所以丢包很正常。Qt 工程最实用的 3 种方案:


✅ 方案 1:应用层 ACK + 超时重传(最常用,最有效)

原理

  1. 发一包数据
  2. 等待对方回 ACK
  3. 超时没收到 → 重发

Qt 实现代码

cpp

运行

复制代码
// 发送
QUdpSocket *m_udp;
QTimer *m_retryTimer;
QByteArray m_lastSendData;

void sendUdpData(const QByteArray &data)
{
    m_lastSendData = data;
    m_udp->writeDatagram(data, QHostAddress("192.168.1.100"), 8080);
    m_retryTimer->start(300); // 300ms超时
}

// 超时重发
void onRetryTimeout()
{
    m_udp->writeDatagram(m_lastSendData, QHostAddress("192.168.1.100"), 8080);
}

// 收到 ACK 停止重传
void onRecvAck()
{
    m_retryTimer->stop();
}

✅ 方案 2:增加序列号 + 丢包重传请求(可靠 UDP)

  • 每个包带序号
  • 接收方返回缺失序号
  • 发送方补发

适合:视频、实时消息、大量数据传输。


✅ 方案 3:降低发送速率 + 分包发送(简单有效)

UDP 丢包大多是发太快,缓冲区溢出。

cpp

运行

复制代码
// 每发一包延迟 5~10ms,大幅降低丢包
QThread::msleep(8);

✅ 方案 4:FEC 前向纠错(视频 / 语音专用)

发冗余包,丢几个包也能恢复,不需要重传。


✅ 方案 5:心跳 + 重连机制

用于弱网环境。


三、最终总结(Qt 开发必背)

TCP 粘包解决

4 字节长度包头 + 包体按长度拆包,永不粘包!

UDP 丢包解决

  1. ACK 确认 + 超时重传(最有效)
  2. 控制发送速度
  3. 序列号 + 选择重传
  4. FEC 冗余包 (实时场景)

Qt 完整工程:TCP (包头分包防粘包)+ 可靠 UDP (ACK + 超时重传防丢包)

工程结构:服务端 + 客户端两套,基于 QTcpSocket/QUdpSocket,Qt5/Qt6 通用,pro 一键编译

一、工程 pro (共用)

qmake

复制代码
QT += core gui network widgets
CONFIG += c++11
TARGET = NetDemo
TEMPLATE = app
SOURCES += main.cpp \
           tcpserver.cpp tcpclient.cpp \
           udpserver.cpp udpclient.cpp
HEADERS += tcpserver.h tcpclient.h \
           udpserver.h udpclient.h

模块 1:TCP 固定 4 字节大端包头,彻底解决粘包 / 半包

tcpcommon.h (公用打包解包)

cpp

运行

复制代码
#ifndef TCPCOMMON_H
#define TCPCOMMON_H
#include <QByteArray>
#include <QDataStream>
// 打包:4字节长度(大端)+数据体
inline QByteArray tcpPack(const QByteArray& data)
{
    QByteArray buf;
    QDataStream ds(&buf,QIODevice::WriteOnly);
    ds.setByteOrder(QDataStream::BigEndian);
    ds << quint32(data.size());
    buf.append(data);
    return buf;
}
// 拆包逻辑放到接收缓冲区循环解析
#endif

tcpserver.h

cpp

运行

复制代码
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QByteArray>
class TcpServer:public QTcpServer
{
    Q_OBJECT
public:
    explicit TcpServer(QObject*parent=nullptr);
private slots:
    void onNewConn();
    void onReadyRead();
private:
    QByteArray m_recvBuf;
};
#endif

tcpserver.cpp

cpp

运行

复制代码
#include "tcpserver.h"
#include "tcpcommon.h"
#include <QDebug>
TcpServer::TcpServer(QObject *parent):QTcpServer(parent)
{
    listen(QHostAddress::Any,8899);
    connect(this,&QTcpServer::newConnection,this,&TcpServer::onNewConn);
}
void TcpServer::onNewConn()
{
    QTcpSocket*sock=nextPendingConnection();
    connect(sock,&QTcpSocket::readyRead,this,&TcpServer::onReadyRead);
}
void TcpServer::onReadyRead()
{
    QTcpSocket*sock=qobject_cast<QTcpSocket*>(sender());
    m_recvBuf.append(sock->readAll());
    // 循环拆包
    while(1)
    {
        if(m_recvBuf.size()<4) break;
        QDataStream ds(m_recvBuf);
        ds.setByteOrder(QDataStream::BigEndian);
        quint32 len;ds>>len;
        if(m_recvBuf.size()<int(4+len)) break;
        QByteArray pkg=m_recvBuf.mid(4,len);
        qDebug()<<"TCP收到完整报文:"<<pkg;
        // 回发测试
        sock->write(tcpPack("Server Recv OK"));
        // 截去已解析数据
        m_recvBuf=m_recvBuf.mid(4+len);
    }
}

tcpclient.h

cpp

运行

复制代码
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <QTcpSocket>
#include <QByteArray>
class TcpClient:public QTcpSocket
{
    Q_OBJECT
public:
    explicit TcpClient(QObject*parent=nullptr);
    void sendMsg(const QByteArray&data);
private slots:
    void onReadyRead();
private:
    QByteArray m_buf;
};
#endif

tcpclient.cpp

cpp

运行

复制代码
#include "tcpclient.h"
#include "tcpcommon.h"
#include <QDebug>
TcpClient::TcpClient(QObject *parent):QTcpSocket(parent)
{
    connect(this,&QTcpSocket::readyRead,this,&TcpClient::onReadyRead);
    connectToHost("127.0.0.1",8899);
}
void TcpClient::sendMsg(const QByteArray &data)
{
    write(tcpPack(data));
}
void TcpClient::onReadyRead()
{
    m_buf.append(readAll());
    while(1)
    {
        if(m_buf.size()<4) break;
        QDataStream ds(m_buf);
        ds.setByteOrder(QDataStream::BigEndian);
        quint32 len;ds>>len;
        if(m_buf.size()<int(4+len)) break;
        QByteArray pkg=m_buf.mid(4,len);
        qDebug()<<"Client收到:"<<pkg;
        m_buf=m_buf.mid(4+len);
    }
}

模块 2:可靠 UDP(序号 + ACK+300ms 超时重传,解决丢包)

自定义报文格式:[1byte序号][payload],收到包原路回 ACK (序号),发送端未收到 ACK 自动重发

udpcommon.h

cpp

运行

复制代码
#ifndef UDPCOMMON_H
#define UDPCOMMON_H
#include <QByteArray>
// 打包:1字节序号+数据
inline QByteArray udpPack(quint8 seq,const QByteArray&data)
{
    QByteArray p;
    p.append((char)seq);
    p.append(data);
    return p;
}
// ACK包:0xA5+序号
inline QByteArray makeAck(quint8 seq)
{
    QByteArray ack;
    ack.append(char(0xA5));
    ack.append(char(seq));
    return ack;
}
#endif

udpserver.h

cpp

运行

复制代码
#ifndef UDPSERVER_H
#define UDPSERVER_H
#include <QUdpSocket>
class UdpServer:public QUdpSocket
{
    Q_OBJECT
public:
    explicit UdpServer(QObject*parent=nullptr);
private slots:
    void onReadDatagram();
};
#endif

udpserver.cpp

cpp

运行

复制代码
#include "udpserver.h"
#include "udpcommon.h"
#include <QDebug>
UdpServer::UdpServer(QObject *parent):QUdpSocket(parent)
{
    bind(QHostAddress::Any,9988);
    connect(this,&QUdpSocket::readyRead,this,&UdpServer::onReadDatagram);
}
void UdpServer::onReadDatagram()
{
    while(hasPendingDatagrams())
    {
        QHostAddress addr;quint16 port;
        QByteArray dat=readDatagram(pendingDatagramSize(),&addr,&port);
        if(dat.isEmpty())continue;
        quint8 seq=(quint8)dat.at(0);
        QByteArray body=dat.mid(1);
        qDebug()<<"UDP服务端收到数据:"<<body<<"序号"<<seq;
        // 回复ACK
        writeDatagram(makeAck(seq),addr,port);
    }
}

udpclient.h

cpp

运行

复制代码
#ifndef UDPCLIENT_H
#define UDPCLIENT_H
#include <QUdpSocket>
#include <QTimer>
#include <QMap>
class UdpClient:public QUdpSocket
{
    Q_OBJECT
public:
    explicit UdpClient(QObject*parent=nullptr);
    void sendUdpData(const QByteArray&data);
private slots:
    void onRead();
    void onTimeout();
private:
    QTimer*m_timer;
    quint8 m_seq=1;
    QByteArray m_lastPkg;
    QHostAddress m_svrAddr=QHostAddress("127.0.0.1");
    quint16 m_svrPort=9988;
};
#endif

udpclient.cpp

cpp

运行

复制代码
#include "udpclient.h"
#include "udpcommon.h"
#include <QDebug>
UdpClient::UdpClient(QObject *parent):QUdpSocket(parent)
{
    m_timer=new QTimer(this);
    m_timer->setInterval(300); //300ms超时重传
    connect(m_timer,&QTimer::timeout,this,&UdpClient::onTimeout);
    connect(this,&QUdpSocket::readyRead,this,&UdpClient::onRead);
}
void UdpClient::sendUdpData(const QByteArray &data)
{
    m_lastPkg=udpPack(m_seq,data);
    writeDatagram(m_lastPkg,m_svrAddr,m_svrPort);
    m_timer->start();
}
void UdpClient::onRead()
{
    QHostAddress addr;quint16 port;
    QByteArray d=readDatagram(pendingDatagramSize(),&addr,&port);
    if(d.size()!=2 || d.at(0)!=char(0xA5)) return;
    //收到ACK,停止重传
    m_timer->stop();
    m_seq++; //序号自增
    qDebug()<<"收到ACK,发送成功";
}
void UdpClient::onTimeout()
{
    //超时重发
    writeDatagram(m_lastPkg,m_svrAddr,m_svrPort);
    qDebug()<<"UDP超时重传";
}

main.cpp 测试入口

cpp

运行

复制代码
#include <QCoreApplication>
#include "tcpserver.h"
#include "tcpclient.h"
#include "udpserver.h"
#include "udpclient.h"
#include <QThread>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc,argv);
    //TCP测试
    TcpServer srvTcp;
    TcpClient cliTcp;
    cliTcp.sendMsg("第一个数据包");
    QThread::msleep(100);
    cliTcp.sendMsg("第二个数据包");

    //UDP测试
    UdpServer srvUdp;
    UdpClient cliUdp;
    cliUdp.sendUdpData("UDP测试数据1");
    return a.exec();
}

二、关键原理说明

TCP 防粘包要点

  1. 固定 4 字节大端包头存储数据长度,是工业标准方案;
  2. 接收侧用m_recvBuf缓存所有数据,循环解析:不足 4 字节等下次、长度不够等下次、够长截取报文,剩余数据留在缓冲区,彻底杜绝粘包 / 半包。

UDP 防丢包三层保障

  1. 应用 ACK 应答:客户端发包→服务端回对应序号 ACK,收到 ACK 停止重发;
  2. 300ms 超时重传:丢包无 ACK 自动补发,解决链路丢包;
  3. 单包有序号 ,可扩展:接收方缺序号请求补发 (选择重传)、发送限流msleep(5~10ms)防止发送过快缓冲区溢出丢包;

三、扩展优化 (按需添加)

  1. UDP 限流:高频发送场景QThread::msleep(8),降低网卡满载丢包;
  2. 重传次数上限:最多重传 3 次,超过判定断开;
  3. FEC 前向纠错:音视频场景附加冗余包,丢包不解码。

Qt 可靠 UDP 心跳 + 自动重连 完整可运行代码

这是工业级最常用方案心跳包 + 超时丢包判定 + 自动重连 / 重发机制 彻底解决 UDP 丢包、断线、无响应问题。


核心原理(一句话)

  1. 客户端定时发心跳(每 3 秒)
  2. 服务端收到必须回心跳应答
  3. 连续 3 次收不到应答 → 判断断开
  4. 断开后自动重连、重发数据

完整代码(直接复制用)

1. 全局定义(udpheartbeat.h)

cpp

运行

复制代码
#ifndef UDPHEARTBEAT_H
#define UDPHEARTBEAT_H

// 心跳指令
#define UDP_HEART_BEAT      "HB"
#define UDP_HEART_ACK       "HB_ACK"

// 超时配置
#define HB_INTERVAL         3000    // 3秒发一次心跳
#define HB_MAX_MISS         3       // 最多丢3次 → 断开

#endif // UDPHEARTBEAT_H

2. 客户端代码(带心跳 + 重连)

udpclient.h

cpp

运行

复制代码
#ifndef UDPCLIENT_H
#define UDPCLIENT_H

#include <QUdpSocket>
#include <QTimer>
#include <QObject>

class UdpClient : public QObject
{
    Q_OBJECT
public:
    explicit UdpClient(QObject *parent = nullptr);
    void sendData(const QByteArray &data);   // 发送业务数据

private slots:
    void sendHeartBeat();    // 发送心跳
    void onRecvData();       // 接收数据
    void checkTimeout();     // 检测心跳超时

private:
    void reconnect();        // 重连机制

    QUdpSocket *m_udp;
    QTimer *m_hbTimer;       // 心跳定时器
    QTimer *m_checkTimer;    // 超时检测定时器
    int m_hbMissCount;       // 丢失心跳次数
    bool m_isConnected;      // 连接状态

    QHostAddress m_svrIp;
    quint16 m_svrPort;
};

#endif // UDPCLIENT_H

udpclient.cpp

cpp

运行

复制代码
#include "udpclient.h"
#include "udpheartbeat.h"
#include <QDebug>

UdpClient::UdpClient(QObject *parent) : QObject(parent)
{
    m_udp = new QUdpSocket(this);
    m_hbTimer = new QTimer(this);
    m_checkTimer = new QTimer(this);

    m_svrIp = QHostAddress("127.0.0.1");
    m_svrPort = 8888;
    m_hbMissCount = 0;
    m_isConnected = false;

    // 3秒发一次心跳
    m_hbTimer->start(HB_INTERVAL);
    // 每3.5秒检测超时
    m_checkTimer->start(HB_INTERVAL + 500);

    connect(m_hbTimer, &QTimer::timeout, this, &UdpClient::sendHeartBeat);
    connect(m_checkTimer, &QTimer::timeout, this, &UdpClient::checkTimeout);
    connect(m_udp, &QUdpSocket::readyRead, this, &UdpClient::onRecvData);

    qDebug() << "UDP 客户端启动,带心跳重连机制";
}

// 发送心跳包
void UdpClient::sendHeartBeat()
{
    m_udp->writeDatagram(UDP_HEART_BEAT, m_svrIp, m_svrPort);
}

// 接收服务端消息
void UdpClient::onRecvData()
{
    while (m_udp->hasPendingDatagrams())
    {
        QByteArray buf;
        buf.resize(m_udp->pendingDatagramSize());
        m_udp->readDatagram(buf.data(), buf.size());

        // 收到心跳应答 → 心跳重置
        if (buf == UDP_HEART_ACK)
        {
            m_hbMissCount = 0;
            m_isConnected = true;
            return;
        }

        // 处理业务数据...
        qDebug() << "收到业务数据:" << buf;
    }
}

// 超时检测(核心)
void UdpClient::checkTimeout()
{
    if (!m_isConnected)
    {
        reconnect(); // 未连接 → 重连
        return;
    }

    m_hbMissCount++;
    qDebug() << "丢失心跳次数:" << m_hbMissCount;

    // 连续丢3次 → 断开
    if (m_hbMissCount >= HB_MAX_MISS)
    {
        qDebug() << "心跳超时,UDP 已断开!";
        m_isConnected = false;
        m_hbMissCount = 0;
    }
}

// 重连机制
void UdpClient::reconnect()
{
    qDebug() << "尝试重新连接服务端...";
    sendHeartBeat(); // 重发心跳
}

// 发送业务数据
void UdpClient::sendData(const QByteArray &data)
{
    if (m_isConnected)
        m_udp->writeDatagram(data, m_svrIp, m_svrPort);
    else
        qDebug() << "未连接,无法发送数据";
}

3. 服务端代码(应答心跳)

udpserver.h

cpp

运行

复制代码
#ifndef UDPSERVER_H
#define UDPSERVER_H

#include <QUdpSocket>
#include <QObject>

class UdpServer : public QObject
{
    Q_OBJECT
public:
    explicit UdpServer(QObject *parent = nullptr);

private slots:
    void onRecvData();

private:
    QUdpSocket *m_udp;
};

#endif // UDPSERVER_H

udpserver.cpp

cpp

运行

复制代码
#include "udpserver.h"
#include "udpheartbeat.h"
#include <QDebug>

UdpServer::UdpServer(QObject *parent) : QObject(parent)
{
    m_udp = new QUdpSocket(this);
    m_udp->bind(8888);

    connect(m_udp, &QUdpSocket::readyRead, this, &UdpServer::onRecvData);
    qDebug() << "UDP 服务端启动,监听 8888 端口";
}

void UdpServer::onRecvData()
{
    while (m_udp->hasPendingDatagrams())
    {
        QByteArray buf;
        QHostAddress addr;
        quint16 port;

        buf.resize(m_udp->pendingDatagramSize());
        m_udp->readDatagram(buf.data(), buf.size(), &addr, &port);

        // 收到心跳 → 必须回 ACK
        if (buf == UDP_HEART_BEAT)
        {
            m_udp->writeDatagram(UDP_HEART_ACK, addr, port);
            qDebug() << "心跳应答已回复";
        }
        else
        {
            qDebug() << "收到客户端数据:" << buf;
        }
    }
}

4. 测试 main.cpp

cpp

运行

复制代码
#include <QCoreApplication>
#include "udpserver.h"
#include "udpclient.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    UdpServer server;
    UdpClient client;

    client.sendData("我是客户端业务数据");

    return a.exec();
}

这个机制到底解决了什么?

✔ 心跳机制

每 3 秒发一次心跳,确保双方在线。

✔ 超时判断

连续 3 次没收到心跳 → 判断断开。

✔ 自动重连

断开后自动重试、自动恢复连接。

✔ 可靠 UDP 基础

有了心跳,你就可以继续扩展:

  • 重发机制
  • 序号机制
  • 丢包重传

大白话总结

plaintext

复制代码
发心跳 → 等应答 → 连续3次不应答 → 判定断开 → 自动重连

这就是 工业级可靠 UDP 的标准方案

相关推荐
Quz3 天前
QML Hello World 入门示例
qt
xcyxiner6 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner7 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner7 天前
DicomViewer (添加模型类)3
qt
xcyxiner8 天前
DicomViewer (目录调整) 2
qt
xcyxiner8 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
treesforest10 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
桥田智能10 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G10 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt
江华森10 天前
TCP/IP 协议栈实战 — 7 个实验详解
网络·tcp/ip·智能路由器