我刚开始使用C ++进行一些原始网络编程,并且已经在我的Raspberry Pi上进行编译(没有交叉编译)。这使得一切都变成了小尾巴。
在构建我的IP头之后,我计算了IP校验和,但它总是出错(基于这里的示例http://www.thegeekstuff.com/2012/05/ip-header-checksum/)。
重新启动gdb,我的问题已经解决了IP头中前32位的排序问题。该示例使用0x4500003C
,即版本4(0x4
),IHL 5(0x5
),TOS 0(0x00
)和tot_length 60(0x003C
)。所以我把我的数据包设置为相同。
struct iphdr* ip; // Also some mallocing
ip->version = 4;
ip->ihl = 5;
ip->tos = 0;
ip->tot_len = 60;
现在在gdb中,我检查了前32位,由于字节顺序而期待0x3C000045
,但我得到了这个:
(gdb) print ip
$1 = (iphdr *) 0x11018
(gdb) x/1xw 0x11018
0x11018: 0x003c0045
前16位是小端(0x0045
),但第二位包含十进制60,似乎是大端(0x003C
)!
是什么给这个?我疯了吗?我对结构体内的字节顺序完全错了吗? (这是一个明确的可能性)
答案 0 :(得分:7)
结构中的字段顺序,然后是多字节字段中的字节顺序。
0x003C
根本不是字节序,它是60的十六进制值。当然,它存储在内存中,带有一些字节顺序,但是你用来写字段的顺序和用来读它的顺序out是相同的 - 两者都是Raspberry Pi的本机字节顺序,它们会被取消。
通常你会写:
ip->tot_len = htons(60);
将16位字段存储到数据包中时。还有htonl
用于32位字段,ntohs
和ntohl
用于从网络数据包中读取字段。
答案 1 :(得分:1)
ARM体系结构可以运行小端和大端,但Android平台运行小端。