博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
大小字节序
阅读量:6440 次
发布时间:2019-06-23

本文共 1969 字,大约阅读时间需要 6 分钟。

这是我的博客真正内容的第一篇,就从最近工作上遇到的一个问题开始吧——大小端字节序

首先我先从简单的概念开始介绍大小端字节序吧:

概念:

  字节序是指多字节数据在计算机内存中存储或者网络传输时各字节序的存储顺序(我从网上找到的,个人认为这句表达的已经很明确了)

下面是常见的字节序:

1、Little endian(小端字节序LE):就是低位放在低地址,高位放在高地址;

2、Big endian(大端字节序BE):就是低位放在高地址,高位放在低地址;

eg:将0x12345678写到以0x0000开始的内存中,有以下结论:

地址            LE            BE

0x0000       0x78        0x12

0x0001       0x56        0x34

0x0002       0x34        0x56

0x0003       0x12        0x78

以上就是最基本的知识点了,下面介绍做项目需要的一些基础知识吧:

网络字节序:

  网络字节序是TCP/IP中规定的一种数据表示格式,这与操作系统、CPU等无关,这里我们应该察觉到,既然与操作系统以及硬件无关的话,说明在TCP/IP的协议之下,信息的传输是不需要做大写端字节序的转换的,我想这也是TCP/IP协议的一个强大之处,还有一点就是网络字节顺序都是采用BE,也就是上面我们所介绍的大端字节序

既然有了这几种字节序,那么我们可以想象,当两台不同字节序的主机之间进行通信的话,如果我们不采取一定的措施,比如说上面的例子中,就会被解释为不同的数据,这就会造成数据的错乱,这样的话,你要做的项目自然会是以失败告终,那么如何处理类似这种事件呢?下面我来介绍一下大小端字节序、以及大小端字节序与网络字节序是如何进行转换的:

其实很简单比如说在一个系统中一个数被理解为A-B-C-D(A/B/C/D各占8位),我们只要把它变为D-C-B-A即可。下面是一个宏块的操作:

#define ChangeEndian(in) ( ( (in >> 24) & 0xff) | ( (in >> 8) & 0xff00) | ( (in << 8) & 0xff0000) | (in << 24))/*4字节*/

#define ChangeEndian(in) ( ( (in >> 8) & 0xff) | (in << 8))/*2字节*/

上面两个语句,就是实现大小端字节序的转换,具体的理解,大家可以按照实现的方法来一遍,其实也挺简单的;好了下面我将介绍几个函数(bsd socket提供的转换函数),这几个函数在网络通信时有存在的必要

1、htons()把unsigned short类型从主机序转换到网络序

2、htonl()把unsigned long类型从主机序转换到网络序

3、ntohs()把unsigned short类型从网络序转换到主机序

4、ntohl()把unsigned long类型从网络序转换到主机序

由于网络字节序都是BE,所以在BE类型的系统中,这些函数定义成空宏。

在做到网络开发或者是跨平台项目时,需要注意字节序的问题。

下面是我自己写的一个简单的测试系统的字节序的程序

#include <stdio.h>

#define ChangeEndian(in) ( ( (in >> 24) & 0xff) | ( (in >> 8) & 0xff00) | ( (in << 8) & 0xff0000) | (in << 24))/*4字节*/

int main(int argc, char** argv)

{

  int i_num = 0x12345678;

  int j_num = 0x12;

  printf("[0]:0x%x\n", *((char*)&i_num + 0) );

  printf("[1]:0x%x\n", *((char*)&i_num + 1) );

  printf("[2]:0x%x\n", *((char*)&i_num + 2) );

  printf("[3]:0x%x\n", *((char*)&i_num + 3) );

  if(j_num == *((char*)&i_num + 3))

  {

    printf("The endian of this System is LE\n");

  }

  else

  {

    printf("The endian of this System is BE\n");

  }

  return 1;

}

 对于枚举类型的数据进行转换时需要强制转换一下,再赋值给原变量

转载于:https://www.cnblogs.com/jpf-blog/archive/2013/03/25/2980729.html

你可能感兴趣的文章
职场邮件忌讳
查看>>
[译]编写可测试的JavaScript代码
查看>>
Golang信号处理和优雅退出守护进程
查看>>
centos源整理
查看>>
第二十讲:tapestry组件详解之BeanDisplay
查看>>
Android 第五课——Activity基础
查看>>
编写软件动态加载NT式驱动
查看>>
sqlite数据类型 datetime处理
查看>>
在Qt自带例子中添加HideItem,并实现相应Undo和Redo功能
查看>>
用php解析时间戳做时间间隔“几分钟前,几秒前,几小时前”......
查看>>
JavaScript Cookie 的正确用法
查看>>
Android Studio 3.X打开DDMS
查看>>
如何在debian下通过wget安装chrome浏览器
查看>>
豆果第四天
查看>>
Saltstack+Shell自动化分发脚本
查看>>
linux常用命令之压缩及解压
查看>>
collect2: ld returned 1 exit status
查看>>
泛型的概述
查看>>
TWaver矢量小试——Android演进路线图
查看>>
华为手机真机调试设置
查看>>