网络序和主机序、大端和小端问题详解

网络序和主机序、大端和小端问题详解


目录

网络序和主机序、大端和小端问题详解

1. 什么是网络序、主机序、大端、小端

2. 为什么要区分大端与小端

3. 什么时候需要转换大端与小端

4. 实际验证

5. 如果场景是host1发送tcp报文报文至host2,但是host2接收时并未进行网络序转主机序,那么将会出现什么情况?

6. 总结

 

1. 什么是网络序、主机序、大端、小端


大端、小端都指的是一种存储方式,网络字节序使用的是大端方式,大部分计算机使用的是小端模式。

  • 大端

    高位存放在低地址,低位存放在高地址。数据字节位随着内存地址的增长而减小。

    大端即网络抓包时看起来舒服的那种字节序,符合我们的阅读习惯

  • 小端

    高位存放在高地址,低位存放在低地址。数据字节位随着内存地址的增长而增长。

    小端存储阅读时是反人类的,但是有利于计算机硬件低位计算的方式

2. 为什么要区分大端与小端


  • cpu硬件设计中,为了方便计算一般都是从低位计算的,小端存储方式有利于低位计算。

  • 但是小端方式不利于我们阅读,网络上进行抓包时使用大端方式解决了这个问题。

3. 什么时候需要转换大端与小端


  • 内存存储以Byte为单位,当涉及一个Byte的变量存储时是没有区分的

  • c语言中内置的数据类型有int、double、short等多字节类型,存储该类型时将有两种方式,即上述的大端(低地址高位)与小端(低地址低位),这类的变量在由host1发送至host2时,需要进行大小端转换,即host1发往网络进行hton,host2接收时进行网络序转主机序。

4. 实际验证


  • 主机序、小端验证

    使用UINT16短整型变量存储以太帧类型,使用0x0800为例,利用gdb查看实际内存存储

(gdb) l
1    #include<stdio.h>
2    
3    int main()
4    {
5        unsigned short eth_type=0x0800;
6    
7        return 1;
8    }

(gdb) b main
Breakpoint 1 at 0x400478: file gdb_test.c, line 5.
(gdb) r
Starting program: /home/fdu/Desktop/gdb_test 

Breakpoint 1, main () at gdb_test.c:5
5        unsigned short eth_type=0x0800;
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.212.el6.x86_64
(gdb) n
7        return 1;
(gdb) p/x eth_type
$1 = 0x800
(gdb) x/2xb &eth_type
0x7fffffffe50e:    0x00    0x08

可以发现0x0800实际在计算机中存储时使用小端方式,(0x0008),但是在代码中我们并不用感知该存储方式。

  • 网络序、大端验证

通过抓包可以看到网络字节流中,0x0800存储为大端方式(0x0800)。

5. 如果场景是host1发送tcp报文报文至host2,但是host2接收时并未进行网络序转主机序,那么将会出现什么情况?


报文字节流是网络字节序,host2接收后并未进行主机序转换(仍以大端存储),此时如果进行报文解析(以小端方式解析),解析出来的报文将会出错,以以太帧类型为例

uint8 *raw_buf = m_buf; //指向报文字节流,未进行大小端转换

uint16 eth_type = (uint16 *)(raw_buf + 12); //eth_type存储报文类型,未进行大小端转换

以太帧类型网络字节序为大端0x0800

当原封不动到达主机端,eth_type由强转获取,即内存存储的仍为0x08 0x00

(gdb) x/2xb &eth_type

0x7fffffffe50e: 0x08 0x00

但是,需要注意的是此时host2将以小端方式解析该变量,即内存0x7fffffffe50e: 0x08 0x00将解析为0x0008

(gdb) p/x eth_type

$3 = 0x8

6. 总结


  • 大端和小端只是两种存储方式,但是无论如何存储,只要按照各自的解析方式,解析出来的含义是一致的就OK。例如host1为小端存储,host2为大端存储,但是两个计算机中运行的c程序中变量eth_type永远都是0x0800这种我们熟知含义的协议号。所以程序员不用过分关注大小端。

  • 不进行大小端转换,将会导致原来大端模式存储的数据,却以小端存储方式来解读,必然会导致错误。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值