Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Create QByteArray from a packet structure
Forum Updated to NodeBB v4.3 + New Features

Create QByteArray from a packet structure

Scheduled Pinned Locked Moved General and Desktop
5 Posts 4 Posters 17.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    donitaroid
    wrote on last edited by
    #1

    Hi, I want to send a UDP packet to remote server, the packet content is already defined as a struct like this.

    @
    struct MsgPacket {
    char header[20];
    unsigned short len;
    unsigned short cmd;
    unsigned short tag;
    unsigned short flag;
    unsigned int seq;
    char data[512];
    };
    @

    This struct is very useful, I can assign value to the specified position in the buffer.

    @
    packet.len = (size);
    packet.cmd = (eventID);
    packet.tag = 0;
    packet.flag &= ~FLAG_REPLY;
    packet.flag |= FLAG_FINAL;
    packet.seq = 0;
    @

    But there is still some annoying problem. While I was trying to send a packet by the Qt network module, I have to create a QByteArray like this.

    @
    QByteArray datagram = QByteArray(static_cast<char*>((void*)&packet), sizeof(packet));
    senderSocket->writeDatagram(datagram.data(), datagram.size(), QHostAddress::Broadcast, REMOTE_PORT);
    @

    I can replace the QByteArray with char pointer. But the char pointer is not inherited from a QObject. It would make some problem while sending it as signal parameter. So the QByteArray is much preferable.

    Can I improve this code more? It takes a lot of annoying cast and I feel this would not be a good coding style. Thank you in advance.

    1 Reply Last reply
    0
    • A Offline
      A Offline
      AcerExtensa
      wrote on last edited by
      #2

      "QDataStream":http://qt-project.org/doc/qt-4.8/qdatastream.html is the right choice in your situation.

      @
      QByteArray data;
      QDataStream out(&data, QIODevice::WriteOnly);
      out << QString("the answer is");
      out << (qint32)4
      @

      And on other side:
      @
      QByteArray data;
      QDataStream in(&data, QIODevice::ReadOnly);
      in >> your_struct.name >> your_struct.id;
      @

      God is Real unless explicitly declared as Integer.

      1 Reply Last reply
      0
      • JeroentjehomeJ Offline
        JeroentjehomeJ Offline
        Jeroentjehome
        wrote on last edited by
        #3

        THERE IS A BIG BUTT TO IT!!! A lot of desktop programmers forget that you do have to take into account the memory allocation on a byte level! So allocating a byte, a int and then a byte again will result in 3 addresses allocated with a lot of "empty" data. Think about it, first allocate a 1 byte (let's assume a 32 bits system) on a 4 byte address. Then an integer that will be 4 bytes in total, but on a new address. As last a new byte, so you think it will only consist of 6 bytes, but in processor world it would be 12!
        There is a way to fix it though. You need to make sure the struct is allocated without room in between. There are attributes to tell the compiler it has to crop the struct.
        @
        #pragma pack(1) // 1 byte alignment
        typedef struct
        {
        }
        @
        Have fun coding!

        Greetz, Jeroen

        1 Reply Last reply
        0
        • D Offline
          D Offline
          donitaroid
          wrote on last edited by
          #4

          The data I want to send was binary data(struct), it is not string.

          @
          12 34 56 78 9a bc de f0 00 00 00 00 00 CA FE BA BE FF EE DD CC ...
          |---First field------------------------| |---Second field------------|
          @

          I have to seek to specified position then write it if I was using QDataStream. I want to simply assign a value to the structure member. Maybe the QDataStream is not suit for my situation.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            AlekseyOk
            wrote on last edited by
            #5

            You can use @QByteArray::append(const char*, int)@ and @QByteArray::fromRawData(const char*, int)@

            Be careful with this methods and take a look to Jeroentje@home's post.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved