2015-06-29 38 views
2

我已经在原始套接字开始一个冒险,我发现一个IP报头,我不明白,我的疑问是叶结构参数C

  • hdrlen:4

这两分四点用于什么?

  • 属性((填充));

什么是这个属性?

struct iphdr { 
    uint8_t hdrlen:4; 
    uint8_t version:4; 
    uint8_t ecn:2;  // Explicit Congestion Notification - RFC 3168 
    uint8_t dscp:6;  // DiffServ Code Point 
    uint16_t length; 
    uint16_t ident; 
    uint16_t fragoff:13; 
    uint16_t flags:3; 
    uint8_t ttl; 
    uint8_t protocol; 
    uint16_t checksum; 
    uint32_t srcip; 
    uint32_t dstip; 
    uint32_t options[ ]; // Present if hdrlen > 5 
} __attribute__((__packed__)); 
+0

可能的重复[什么是C++结构语法“a:b”的意思](http://stackoverflow.com/questions/824295/what-does-c-struct-syntax-ab-mean) –

+0

http:///stackoverflow.com/questions/1604968/what-does-a-colon-in-a-struct-declaration-mean-such-as-1-7-16-or-32/1604972#1604972 – thelaws

+0

http:// stackoverflow .com/questions/8568432/is-gccs-attribute-packed-pragma-pack-unsafe – thelaws

回答

4

这个结构表示会通过网络发送的数据包,所以你不想浪费单位空间(因为每一位都需要通过“电线”发送)。

field_name:field_width语法声明了一个bit field,所以uint8_t hdrlen:4;意味着你实际上只需要4位来存储“报头长度”值(但是编译器将确保值被复制到一个uint8_t(一个字节),当你阅读字段值)。

__attribute__((__packed__))语法告诉编译器忽略usual alignment requirements for structs。编译器有时需要在结构字段之间插入填充以确保有效的内存访问结构中的字段。例如,如果在uint8_t之后有一个uint64_t,编译器会在两个字段之间插入填充(垃圾)以确保uint64_t从8字节的边界开始(即指针地址的最后3位全是零)。

正如您所看到的,所有这些位操作和打包都是这样完成的,以便在此结构中没有浪费空间,并且通过网络发送的每一位都是有意义的。