×

关于QT 结构体的使用,socker发送不了0x00的问题

zxjy辉 zxjy辉 发表于2025-01-09 16:32:55 浏览582 评论0

抢沙发发表评论

采用了结构体来确定数据结构,然后使用socker发送不了0x00,正常socker是可以发送0x00的


结构体定义

// 起始帧+结束帧
struct  _YmodemStartEndFrame
{
    uint8_t frameHeader;            // 帧头
    uint8_t packetNumber;           // 包号
    uint8_t packetNumberR;          // 包号反码
    uint8_t NUL[PACKET_SIZE];       // 数据存储区
    uint8_t crc16H;                 // CRC校验位高
    uint8_t crc16L;                 // CRC校验位低

};

错误的引用

// 打包起始帧
QByteArray Ymodem::YmodemStartFramePacking(QString fileName, int size_byte)
{
    YmodemStartEndFrameType start ;                             // 起始帧
    int8_t fileNameQByteArraySize = fileName.toLatin1().size(); // 文件名 大小
    start.frameHeader = SOH;                                    // 帧头
    start.packetNumber = 0x00;                                  // 包号
    start.packetNumberR = SOH;                                 // 包号反码
    start.crc16H = 0x00;
    start.crc16L = 0x00;
    // 先填充0
    memset(start.NUL,'\0',128);
////    // 文件名
////    memcpy(start.NUL,fileName.toLatin1().data(),fileNameQByteArraySize);  // 拷贝文件名
//////    start.NUL[fileNameQByteArraySize] = '\0';                             // 插入字符0,表示文件名结束
////    // 文件大小
////    memcpy(start.NUL+fileNameQByteArraySize+1,QString::number(size_byte,16).toLatin1().data(),sizeof(QString::number(size_byte,16))); // 拷贝文件大小
//////    start.NUL[fileName.toLatin1().size()] = '\0';                                          // 插入字符0,表示文件大小结束
    QByteArray da((char*)&start);
    return da;
}

此时返回的是QByteArray类型的数据,在使用socker.write()发送的时候,会只发送到第二个字节结束,即使在socker.write()方法中规定了发送的字节数,也是一样的,剩余的数据都变成随机的数据,为题就在于 使用  QByteArray da((char*)&start) 构造对象的时候,会被误认为是字符串的结束符,所以就导致了在返回的时候,被截断

正确的引用

// 打包起始帧
YmodemStartEndFrameType *Ymodem::YmodemStartFramePacking(QString fileName, int size_byte)
{
    YmodemStartEndFrameType *start = new YmodemStartEndFrameType(); // 起始帧
    int8_t fileNameQByteArraySize = fileName.toLatin1().size(); // 文件名 大小
    uint16_t crc;
    start->frameHeader = SOH;                                       // 帧头
    start->packetNumber = 0x00;                                     // 包号
    start->packetNumberR = 0xFF;                                    // 包号反码
    // 填充0
    memset(start->NUL,'\0',PACKET_SIZE);
    // 文件名
    memcpy(start->NUL,fileName.toLatin1().data(),fileNameQByteArraySize);  // 拷贝文件名
    // 文件大小
    memcpy(start->NUL+fileNameQByteArraySize+1,QString::number(size_byte,16).toLatin1().data(),sizeof(QString::number(size_byte,16))); // 拷贝文件大小
    // 计算crc
    crc = CRC16_Xmodem((char*)start->NUL,PACKET_SIZE);
    start->crc16H = (crc&0xFF00)>>8;
    start->crc16L = crc&0x00FF;
    // 返回数据
    return start;
}

此时返回的是一个结构体指针(也可以是结构体),这个时候,使用socker.write()方法就可以完整无误的发送出整串数据 PS:在使用socker.write()方法的时候,需要将YmodemStartEndFrameType结构体指针转为char类型的指针。

image.png

其他解决方案

image.png

image.png

image.png

#好好学习!

群贤毕至

访客