Questions about putting real bytes in the payload

142 views
Skip to first unread message

Qi Xiao

unread,
Apr 11, 2022, 11:50:45 AM4/11/22
to ns-3-users

Hi all,

Now I’m developing a TCP application that can transmit the payload with actual data. The script below is one method for creating payload with the contents that I want. But I have one question about this method.

uint8_t *buffer = ...; 

uint32_t size = ...; 

Ptr<Packet> p = Create<Packet> (buffer, size);

Uint8_t *buffer = …;   This means the created pointer ‘buffer’ points to unit8_t variable. so for the contents, only char can be put into the payload? If I want to send a 16 bits number, do I have to separate the 16 bits number to two 8 bits number?

Any help is appreciated.

Thanks.

Gabriel Ferreira

unread,
Apr 11, 2022, 7:54:47 PM4/11/22
to ns-3-users
You can put any data you want, but you either need to serialize it, and deserialize it on the other side, or provide a casted raw pointer.
An example:

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include <iostream>
using namespace ns3;
int
main ()
{
  //Define custom data type
  struct oneStruct{
    int32_t i;
    uint8_t s;
    double d;
  };

  //Fill data fields
  oneStruct instance{-1,(uint8_t)'A',9.1};

  // Copy bytes from the object in memory
  // WARNING: layout depends on data sizes, compiler, low/big endian, etc
  Ptr<Packet> p = Create<Packet> ((uint8_t*)&instance, sizeof(struct oneStruct));

  //Create another structure
  struct oneStruct anotherInstance{0, 0, 0.0};

  //Copy data from packet back to that structure
  p->CopyData ((uint8_t*)&anotherInstance, sizeof(struct oneStruct));

  //Print fields to show it really does what it is supposed to
  std::cout << anotherInstance.i << "\n" << anotherInstance.s << "\n" << anotherInstance.d << std::endl;
}

Qi Xiao

unread,
Apr 14, 2022, 9:00:30 AM4/14/22
to ns-3-users
Hi Gabriel,

Thank you very much ! This problem was perfectly solved. But I do not quite understand why the buffer pointer is set to uint8_t type. 

Gabriel Ferreira

unread,
Apr 14, 2022, 9:57:45 AM4/14/22
to ns-3-users
uint8_t is an unsigned/"raw" byte. 
When you do this type of casting, you tell the compiler to interpret whatever data there is starting at the address in the pointer (&data) as that specific type.

#include <iostream>
int main()
{
    union eg{
        uint16_t a;
        uint8_t b[2];
    };
    union eg variable;
    variable.a = 0xCAFE;
    std::cout << std::hex << (int)variable.b[0] << (int)variable.b[1] << std::endl; // same thing using an union
    std::cout << std::hex << (int)((uint8_t*)&variable.a)[0] << (int)((uint8_t*)&variable.a)[1] << std::endl; // casting the pointer of a different type to access individual bytes
    // these two will probably print "feca" instead of "cafe", since little-endian architectures start storing from the least significant bytes to the most significant bytes
    return 0;
}

ns3 beginner

unread,
May 17, 2022, 9:11:28 AM5/17/22
to ns-3-users
Hi 
Is it possible for you to share your code, if available on Git or open source,  because I am trying to build similar tcp application but it is not working.

Tommaso Pecorella

unread,
May 23, 2022, 4:56:03 AM5/23/22
to ns-3-users
Please describe your problem - "it is not working"  is a bit too few to guess what your problem is.
Reply all
Reply to author
Forward
0 new messages