将结构从小端转换为大端

时间:2018-12-30 12:02:11

标签: c endianness

我的问题是将指针的结构从小字节序转换为大字节序,以便可以将其发送到网络,因为我的结构是12字节或92位,因此我无法应用给定的任何标准或非标准函数。

我正在尝试在Linux系统上实现GTPv1U,因为我的结构指针是96位,因此我试图将其分成32位的三个块,然后进行转换,但是我无法破坏它,我也怀疑这不是正确的方法

我的结构代码

typedef struct  __attribute__((__packed__)) GTPv1Uheader{
    UInt8  version              :3;
    UInt8  ProtocolTypeFlag     :1;
    UInt8  Spare                :1;
    UInt8  ExtensionFlag        :1;
    UInt8  SequenceNumberFLAG   :1;
    UInt8  NpduNumberFlag       :1;
    UInt8  MessageType;
    UInt16 Length;
    UInt32 TEID;                    
    UInt16 SequenceNumber;
    UInt8  NPDUNumber;
    UInt8  NextExtensionheader;
} GTPv1UheaderT;

值分配

GTPv1UheaderT * IntializeGTP(){
    GTPv1UheaderT *GTPv1UheaderP;
    GTPv1UheaderP = malloc(sizeof(GTPv1UheaderT));
    memset(GTPv1UheaderP, 0, (sizeof(GTPv1UheaderT)));
    GTPv1UheaderP->version              = 0x1;
    GTPv1UheaderP->ProtocolTypeFlag     = 0x1;
    GTPv1UheaderP->Spare                = 0x0;
    GTPv1UheaderP->ExtensionFlag        = 0x0;
    GTPv1UheaderP->SequenceNumberFLAG   = 0x1;
    GTPv1UheaderP->NpduNumberFlag       = 0x0;
    GTPv1UheaderP->MessageType          = 0x01;
    GTPv1UheaderP->Length               = 0x000C;
    GTPv1UheaderP->TEID                 = 0x00000001;
    GTPv1UheaderP->SequenceNumber       = 0x0000;
    GTPv1UheaderP->NPDUNumber           = 0x00;
    GTPv1UheaderP->NextExtensionheader  = 0x00;
    return GTPv1UheaderP;
}

预期输出:32 01 00 0C 00 00 00 01 00 00 00 00

实际输出:49 01 0C 00 01 00 00 00 00 00 00 00

编辑:这是交换功能

long s; 
unsigned char k;
k=(unsigned char)GTPv1UheaderP;
s=(unsigned int)k;
s=ntohl(s);
printf("%ld\n",s);

我知道这是行不通的,因为我的long是32位,而指针是96位。任何其他解决方案

1 个答案:

答案 0 :(得分:3)

将整个struct转换为小端或小端或大端都没有意义,因为字节序是多字节标量类型表示形式的属性,例如单个UInt16UInt32。将struct转换为其“在线表示”时,您一次要遍历一个元素,并逐个元素地准备其表示。

位字段代表一种特殊情况,因为它们的顺序是实现定义的。您需要按照自己喜欢的顺序将它们序列化为一个字节。使用hton / ntoh函数来转换单个多字节元素,即LengthTEID