网络字节序与字节内比特序

本文通过IP首部ip.h的结构解析了网络字节序与字节内比特序的概念。阐述了不同字节序下数据字段的排列方式,并讨论了小端与大端机器上数据的组织形式及其对网络传输的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、网络字节序

(上图来自网络,侵删)

本次讨论以IP首部ip.h为例。
struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN 
	u_char	ip_hl:4,		/* header length */
	ip_v:4;			/* version */
#endif
#if BYTE_ORDER == BIG_ENDIAN 
	u_char	ip_v:4,			/* version */
	ip_hl:4;		/* header length */
#endif
	u_char	ip_tos;			/* type of service */
	short	ip_len;			/* total length */
	u_short	ip_id;			/* identification */
	short	ip_off;			/* fragment offset field */
#define	IP_DF 0x4000			/* dont fragment flag */
#define	IP_MF 0x2000			/* more fragments flag */
	u_char	ip_ttl;			/* time to live */
	u_char	ip_p;			/* protocol */
	u_short	ip_sum;			/* checksum */
	struct	in_addr ip_src,ip_dst;	/* source and dest address */
};

已知网络采用大端字节序。和实验室的JackYang讨论,我们得出结论,上图各个字段是从低地址向高地址排布的。比如源地址字段比目的地址字段的地址低,这样和struct ip中各个字段顺序是匹配的。所谓字节序是 针对某个字段的各个字节来说的。考虑下图的Flag与Fragment offset字段,它们合起来是ip.h中的16位 ip_id字段


JackYang认为wireshark看到的大端顺序。如果是小端机,真实顺序是 Fragment offset字段13个bit0在低地址,Flag010(0x2)在高地址。

另一个证据是内核网络源码,如下:

注意到占2个字节的IP校验和(iph->check)在重新计算时需要先ntohs再htons。这样在x86小端机可以正确运行。

二、字节内比特序
看到ip.h源码中 ip_hl和ip_v的位置关系(header length与version的位置关系),一个困扰我很久的历史遗留问题浮现脑海:字节内的比特顺序应该也和大小端有关!
答案的确如此。x86为小端序,它采用LSB 0 bit numbering,故ip_v在 ip_hl之后。
以下详细解答参见: https://www.wikiwand.com/en/Bit_numbering






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值