QT bin二进制文件读写发送

//通讯协议: 0x55,0xAA,datalen(2),total_packet(2),cur_packet(2), data(1024), checksum(1)
const static int PACKET_SIZE      = 1024;//每次发送的字节数
const static int PACKET_HEAD_SIZE = 10;  //协议字节数
void MainWindow::sendBinFile(const QString& filePath)
{
    QFile file;
    file.setFileName(filePath);
    QFileInfo fileInfo(filePath);
    auto fileLen = fileInfo.size();//待发送文件大小
    auto sendCnt = (int)ceil(fileLen / (PACKET_SIZE*1.0));//发送次数
    auto lastLen = fileLen % PACKET_SIZE;//最后一次发送的大小
    if(0 == lastLen){//恰巧是PACKET_SIZE的整数倍
        lastLen = PACKET_SIZE;
    }
    qDebug()<<"fileLen,lastLen,sendCnt:"<< fileLen << lastLen << sendCnt;
    if(file.open(QIODevice::ReadOnly)){
        QDataStream dataStream(&file);
        char *pBuf = new char[fileLen];
        memset(pBuf, 0, fileLen);
        dataStream.readRawData(pBuf,fileLen);
        //qDebug()<<QString::asprintf("%02X %02X",(uint8_t)pBuf[0],(uint8_t)pBuf[1]);
        //qDebug()<<QString::asprintf("%02X %02X",(uint8_t)pBuf[fileInfo.size()-2],(uint8_t)pBuf[fileInfo.size()-1]);
        for(int i = 0; i < sendCnt; i++){
#if 0 //测试文件原始数据输出
            QString strAll;
            if(i != sendCnt - 1){
                for(int k=0;k<PACKET_SIZE;k++){
                    strAll += QString::asprintf("%02X ",(uint8_t)pBuf[i*PACKET_SIZE + k]);
                }
            }else{
                for(int k=0;k<lastLen;k++){
                    strAll += QString::asprintf("%02X ",(uint8_t)pBuf[i*PACKET_SIZE + k]);
                }
            }
            qDebug()<<strAll;
            continue;
#endif
            if(i != sendCnt - 1){
                 const int PACKET_LEN = PACKET_HEAD_SIZE + PACKET_SIZE;
                 //数据填充---------------------------------------------------
                 char tx_buf[PACKET_LEN] = {0};
                 //1: head
                 tx_buf[0] = 0x55;
                 tx_buf[1] = (uint8_t)0xAA;
                 tx_buf[2] = PACKET_LEN >> 8;//数据长度
                 tx_buf[3] = PACKET_LEN & 0xFF;
                 tx_buf[4] = sendCnt >> 8;//总包数
                 tx_buf[5] = sendCnt;
                 tx_buf[6] = (i + 1) >> 8;//当前包数
                 tx_buf[7] = i + 1;
                 //2: data
                 memcpy(tx_buf+8, pBuf+i*PACKET_SIZE, PACKET_SIZE);
                 //3: checksum
                 int8_t checksum(0);
                 for(int j = 0; j < PACKET_LEN-1; j++){
                     checksum += tx_buf[j];
                 }
                 tx_buf[PACKET_LEN-1] = checksum;
#if 0//debug out
                 QString strAll;
                 for(int k=0;k<PACKET_LEN;k++){
                     strAll += QString::asprintf("%02X ",(uint8_t)tx_buf[k]);
                 }
                 qDebug()<<strAll;
#endif
                 //---------------------------------------------------------
                 m_socket.writeDatagram(tx_buf,PACKET_LEN,QHostAddress("192.168.1.10"),8888);
            }else{//最后一次发送
                int PACKET_LEN = PACKET_HEAD_SIZE + lastLen;
                //数据填充---------------------------------------------------
                char *tx_buf = new char[PACKET_LEN];
                memset(tx_buf, 0, PACKET_LEN);
                //1: head
                tx_buf[0] = 0x55;
                tx_buf[1] = (uint8_t)0xAA;
                tx_buf[2] = PACKET_LEN >> 8;//数据长度
                tx_buf[3] = PACKET_LEN & 0xFF;
                tx_buf[4] = sendCnt >> 8;//总包数
                tx_buf[5] = sendCnt;
                tx_buf[6] = (i + 1) >> 8;//当前包数
                tx_buf[7] = i + 1;
                //2: data
                memcpy(tx_buf+8, pBuf+i*PACKET_SIZE, lastLen);
                //3: checksum
                int8_t checksum(0);
                for(int j = 0; j < PACKET_LEN-1; j++){
                    checksum += tx_buf[j];
                }
                tx_buf[PACKET_LEN-1] = checksum;
#if 0//debug out
                QString strAll;
                for(int k=0;k<PACKET_LEN;k++){
                    strAll += QString::asprintf("%02X ",(uint8_t)tx_buf[k]);
                }
                qDebug()<<strAll;
#endif
                //---------------------------------------------------------
                m_socket.writeDatagram(tx_buf,PACKET_LEN,QHostAddress("192.168.1.10"),8888);
                delete []tx_buf;
            }
            //sleep(100);
        }
        delete []pBuf;
    }
    file.close();
}

在这里插入图片描述

Qt可以使用QSerialPort类来发送二进制文件数据。要指定发送到0x2802地址,需要设置串口的波特率、数据位、校验位、停止位等参数,然后使用串口发送数据。要进行分段发送,可以将二进制文件数据分成多个块,每次发送一个块,发送完后等待接收到ACK信号,再发送下一个块。以下是一个示例代码: ```cpp #include <QtCore> #include <QtSerialPort> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 打开串口 QSerialPort serialPort; serialPort.setPortName("COM1"); serialPort.setBaudRate(QSerialPort::Baud115200); serialPort.setDataBits(QSerialPort::Data8); serialPort.setParity(QSerialPort::NoParity); serialPort.setStopBits(QSerialPort::OneStop); serialPort.setFlowControl(QSerialPort::NoFlowControl); if (!serialPort.open(QIODevice::ReadWrite)) { qDebug() << "Failed to open serial port"; return 1; } // 读取二进制文件 QFile file(":/file.bin"); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Failed to open file"; return 1; } QByteArray fileData = file.readAll(); file.close(); // 分块发送 const int blockSize = 1024; const int addr = 0x2802; int offset = 0; while (offset < fileData.size()) { QByteArray block = fileData.mid(offset, blockSize); QByteArray packet; packet.append(char(addr >> 8)); packet.append(char(addr & 0xff)); packet.append(char(block.size() >> 8)); packet.append(char(block.size() & 0xff)); packet.append(block); serialPort.write(packet); serialPort.flush(); qDebug() << "Sent" << packet.size() << "bytes"; // 等待ACK信号 if (!serialPort.waitForReadyRead(5000)) { qDebug() << "Timeout waiting for ACK"; return 1; } QByteArray ack = serialPort.readAll(); if (ack != QByteArray::fromHex("0601")) { qDebug() << "Received invalid ACK" << ack.toHex(); return 1; } qDebug() << "Received ACK" << ack.toHex(); offset += block.size(); } // 关闭串口 serialPort.close(); qDebug() << "Done"; return 0; } ``` 此处的代码仅作参考,实际应用需要根据具体情况进行调整和优化。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值