linux网路编程:字节序(大端、小端、网络、主机)

摘要:
2) Big Endian意味着高阶字节被安排在存储器的低地址端,低阶字节被布置在存储器的高地址端。3) 网络字节顺序:TCP/IP层协议将字节顺序定义为Big Endian,因此TCP/IP协议中使用的字节顺序通常称为网络字节顺序。什么是高位和低位?

字节序:就是数据在内存中的存放顺序,也可称之为端模式。

大端模式和小端模式的定义

1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

2) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

3) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序

什么是高位字节,低位字节?

一般一个16位(双字节)的数据,比如 FF1A (16进制),(4位二进制用一个十六进制表示)
那么高位字节就是FF,低位是1A
如果是32位的数据,比如 3F68415B
高位字(不是字节)是3F68
低位字是415B
右边是低位,左边是高位

include <stdio.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    unsigned int x = 0x12345678;
    unsigned char* p = (unsigned char*)&x;

    //小端字节序
    printf( "%p->%0x
%p->%0x
%p->%0x
%p->%0x
", p+0, *(p+0), p+1, *(p+1), p+2, *(p+2), p+3, *(p+3) );

    printf( "---------------------
" );

    //h:主机字节序    n:网络字节序  l:long
    unsigned int y = htonl( x );    
    p = ( unsigned char* )&y;

    printf( "%p->%0x
%p->%0x
%p->%0x
%p->%0x
", p+0, *(p+0), p+1, *(p+1), p+2, *(p+2), p+3, *(p+3) );

    return 0;
}

输出结果:

0x7fff3bb55708->78
0x7fff3bb55709->56
0x7fff3bb5570a->34
0x7fff3bb5570b->12
---------------------
0x7fff3bb5570c->12
0x7fff3bb5570d->34
0x7fff3bb5570e->56
0x7fff3bb5570f->78

第一种结果:

0x7fff3bb55708->78
0x7fff3bb55709->56
0x7fff3bb5570a->34
0x7fff3bb5570b->12

地址从08--->0b属于增长,   08这个低地址放的是78, 78这个数是低位字节,  这种情况属于低地址放低位字节,高地址放高位字节, 所以叫:小端字节序

第二种结果:

0x7fff3bb5570c->12
0x7fff3bb5570d->34
0x7fff3bb5570e->56
0x7fff3bb5570f->78

把主机字节序转换成了网络字节序, 这种情况属于低地址放高位字节,高地址放低位字节,所以叫:大端字节序

---------------------------------------------------------------------------------------------------------------------------------------------------------

字节序转换相关API:

htonl:主机字节序转换成网络字节序

inet_addr:函数原型:in_addr_t inet_addr(const char *cp)

作用:把ip地址格式转成网络字节序

unsigned int addr = inet_addr( "192.168.1.100" );
printf( "%u
", addr );
printf( "0x%0x
", addr );

结果:

1677830336
0x6401a8c0

这两个数是一样的

ntohl: 网络字节序转主机字节序

unsigned int haddr = ntohl( addr );
printf( "%u
", haddr );
printf( "0x%0x
", haddr );

inet_ntoa:网络字节序,转ip地址格式

struct in_addr ipaddr;
ipaddr.s_addr = addr;
printf( "%s
", inet_ntoa( ipaddr ) );

免责声明:文章转载自《linux网路编程:字节序(大端、小端、网络、主机)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Android适配-资源文件夹命名与匹配规则Zabbix基于CX_ORACLE对Oracle数据库的监控配置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C语言探索之旅 | 第一部分第五课:变量的世界(二),变量声明

作者 谢恩铭,公众号「程序员联盟」。 转载请注明出处。 原文:https://www.jianshu.com/p/8db33987cb49 《C语言探索之旅》全系列 内容简介 变量是什么? 给变量起个名字 变量的类型 声明变量 const 关键字 第一部分第六课预告 1. 变量是什么? 上一课我们学习的是 C语言探索之旅 | 第一部分第四课:变量...

libpcap编程实例

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pcap.h> 4 #include <errno.h> 5 #include <sys/socket.h> 6 #include <netinet/in...

详解2进制,10进制,16进制,8进制,36进制

本篇介绍C/C++语言中的进制的概念,主要介绍2进制、10进制、16进制,这三种是编程时必须掌握的也是最经常使用的。另外,介绍8进制和36进制,当中 36进制在实际project项目中会遇到。 (本文选自《C/C++学习指南》。邵发。附录“2进制,10进制,16进制”)讲2进制、10进制、16进制的视频教程,点击观看  权利声明:作者拥有本书的所有权利。...

由endl对printf和cout的思考

【前言】二者的区别就不介绍了。二者使用方法: printf("%s",a); cout<<a<<endl; endl的作用是什么? 一、endl作用 众所周知,endl有一个换行的作用,第二个作用就是清空缓冲区buffer。 为什么要清空缓冲区呢? 首先思考缓冲区存在的作用,缓冲区的作用一是为了避免频繁的I/O操作对磁盘的损耗,...

第八课:不一样的链表 linux链表设计哲学 5星级教程

这一课最后实现的链表,和普通链表不同,借鉴了linux内核链表的思想,这也是企业使用的链表。 基础介绍: 顺序表的思考 顺序表的最大问题是插入和删除需要移动大量的元素!如何解决?A:在线性表数据元素之间空出位置,为以后插入使用。B:这样不行!中间无论空多少都有可能用完!A:那不是无解了嘛!B:我觉得让每个元素都知道他的下个元素就行了,哪有空插哪  链表...

linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁

Linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量、信号量和读写锁。 下面是思维导图:  一、互斥锁(mutex)   锁机制是同一时刻只允许一个线程执行一个关键部分的代码。 1 . 初始化锁 int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t...