- 浏览: 2031316 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (651)
- ACE (35)
- BAT (9)
- C/C++ (116)
- fast-cgi (14)
- COM (27)
- python (59)
- CGI (4)
- C# (2)
- VC (84)
- DataBase (29)
- Linux (96)
- P2P (6)
- PHP (15)
- Web (6)
- Memcached (7)
- IME输入法 (11)
- 设计模式 (2)
- 搜索引擎 (1)
- 个人情感 (4)
- 笔试/面试 (3)
- 一亩三分地 (33)
- 历史 (2)
- 地理 (1)
- 人物 (3)
- 经济 (0)
- 不仅仅是笑哦 (43)
- 小故事大道理 (2)
- http://www.bjdsmyysjk120.com/ (0)
- http://www.bjdsmyy120.com/ (0)
- 它山之石可以攻玉 (15)
- 大学生你关注些什么 (28)
- 数据恢复 (1)
最新评论
-
luokaichuang:
这个规范里还是没有让我明白当浏览器上传文件时,STDIN的消息 ...
FastCGI规范 -
effort_fan:
好文章!学习了,谢谢分享!
com技术简介 -
vcell:
有错误os.walk(strPath)返回的已经是全部的文件和 ...
通过python获取目录的大小 -
feifeigd:
feifeigd 写道注意:文章中的CPP示例第二行 #inc ...
ATL入门:利用ATL编写简单的COM组件 -
feifeigd:
注意:文章中的CPP示例第二行 #include " ...
ATL入门:利用ATL编写简单的COM组件
long long 类型的网络字节顺序转换 sailor_forever sailing_9806@163.com 转载请注明 http://blog.csdn.net/sailor_8318/archive/2007/08/04/1726064.aspx 做过socket的都知道网络字节转换的事情,网络中传输的数据是纯字节流,没有类型信息,从低地址开始传递;网络字节序通常为大端的,即先传递高字节,因此和大端的本地字节存储顺序一致,和小端的则截然相反。为了数据的一致性,就要把本地的数据转换成网络上使用的格式,然后发送出去,接收的时候也是一样的,经过转换然后才去使用这些数据。基本的库函数中提供了这样的可以进行字节转换的函数,如和htons( ) htonl( ) ntohs( ) ntohl( ),这里n表示network,h表示host,htons( ) htonl( )用于本地字节向网络字节转换的场合,s表示short,即对2字节操作,l表示long即对4字节操作。同样ntohs( )ntohl( )用于网络字节向本地格式转换的场合。随着c99标准的推行,我们伟大的c中增加了新的类型long long int ,unsigned long long int,都是64位的,怎么办?不转肯定是不行,就得自己想办法把它转了。当然有很多方法,我这里想使用一种类比的解决方法,看看如何举一反三。 字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序。其实大部分人在实际的开发中都很少会直接和字节序打交道。唯有在跨平台以及网络程序中字节序才是一个应该被考虑的问题。一次Sun SPARC到Intel X86的平台移植让我们的程序遭遇了“字节序问题”。 在所有的介绍字节序的文章中都会提到字节序分为两类:Big-Endian和Little-Endian。引用标准的Big-Endian和Little-Endian的定义如下: a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。 c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。 首先我们要知道我们C程序映像中内存的空间布局情况:在《C专家编程》中或者《Unix环境高级编程》中有关于内存空间布局情况的说明,大致如下图: ----------------------- 最高内存地址 0xffffffff 。。。。。。 | 栈底 . . 栈 栈顶 ----------------------- | | NULL (空洞) /|\ ----------------------- 堆 ----------------------- 未初始化的数据 ---------------------- (统称数据段) 初始化的数据 ----------------------- 正文段(代码段) ----------------------- 最低内存地址 0x00000000 以上图为例如果我们在栈上分配一个unsigned char buf[4],那么这个数组变量在栈上是如何布局的呢?看下图: 栈底 (高地址) ---------- buf[3] buf[2] buf[1] buf[0] ---------- 栈顶 (低地址) 现在我们弄清了高低地址,接着我来弄清高/低字节,如果我们有一个32位无符号整型0x12345678(呵呵,恰好是把上面的那4个字节buf看成一个整型),那么高位是什么,低位又是什么呢?其实很简单。在十进制中我们都说靠左边的是高位,靠右边的是低位,在其他进制也是如此。就拿0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。 高低地址和高低字节都弄清了。我们再来回顾一下Big-Endian和Little-Endian的定义,并用图示说明两种字节序: 以unsigned int value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value: Big-Endian: 低地址存放高位,如下图: 栈底 (高地址) --------------- buf[3] (0x78) -- 低位 buf[2] (0x56) buf[1] (0x34) buf[0] (0x12) -- 高位 --------------- 栈顶 (低地址) Little-Endian: 低地址存放低位,如下图: 栈底 (高地址) --------------- buf[3] (0x12) -- 高位 buf[2] (0x34) buf[1] (0x56) buf[0] (0x78) -- 低位 --------------- 栈顶 (低地址) 在现有的平台上Intel的X86采用的是Little-Endian,而像Sun的SPARC采用的就是Big-Endian。 假设对于little endian的IA-32架构上面的Linux,首先考虑网络字节转换的结果与原来有什么不同,如 int a = 0x12345678,b = htnl(a),那么就应该是0x78563412。如果是 short c = 0x1234,short d = 0x5678,e = htons(c),f = htons(d),这样e=0x3412,f=0x7856,如果能把e和f调换一下组合放在一起,不就是一个整型a(a=0x12345678)转换之后的值么?实验的代码如下: #include <stdio.h> struct ST{ short val1; short val2; }; union U{ int val; struct ST st; }; int main(void) { int a = 0; union U u1, u2; a = 0x12345678; u1.val = a; printf("u1.val is 0x%x\n", u1.val); printf("val1 is 0x%x\n", u1.st.val1); printf("val2 is 0x%x\n", u1.st.val2); printf("after first convert is: 0x%x\n", htonl(u1.val)); u2.st.val2 = htons(u1.st.val1); u2.st.val1 = htons(u1.st.val2); printf("after second convert is: 0x%x\n", u2.val); return 0; } 输出结果: u1.val is 0x12345678 val1 is 0x5678 val2 is 0x1234 after first convert is: 0x78563412 after second convert is: 0x78563412 按照这种想法我们实现long long int(64bit) 类型,把它分割成两个int(32bit),然后分别使用htonl(),分别转换,然后再将两种int交换顺序重新组合,即实现了整个64位的八个字节的翻转。 代码如下: #include <stdio.h> struct ST{ int val1; int val2; }; union test { long long int val; struct ST st; }; int main(void) { long long int a; union test u1, u2; a = 0x7654321087654321LL; u1.val = a; u2.st.val2 = htonl(u1.st.val1); u2.st.val1 = htonl(u1.st.val2); printf("val1 is 0x%x\n", u2.st.val1); printf("val2 is 0x%x\n", u2.st.val2); printf("u1.val is : 0x%llx\n", u1.val); printf("after convert is : 0x%llx\n", u2.val); return 0; } 执行结果: val1 is 0x10325476 val2 is 0x21436587 u1.val is : 0x7654321087654321 after convert is : 0x2143658710325476 另外注意long long int 最大值是0x7fffffffffffffff,即7后面15个f(2的63次方减1) unsigned long long int 最大值是0xffffffffffffffff,16个f(2的64次方减1)。程序中long long int 可以简写为 long long,但是记住这是简写,就像long是long int的简写。 想看数据在内存中如何存储的,就用gdb吧!使用gdb中 x命令,如 x /xb &a表示要察看存储在变量a中的前一个字节(byte)中的数据(16进制)。x /xw &a 就是要察看变量a中前4个字节(word)数据(16进制)。x /xg &a 察看a开始8个字节的数据。
一、字节序定义
二、高/低地址与高低字节
三、网络字节序的转换
发表评论
-
Berkeley DB 使用经验总结
2012-08-27 14:41 3083作者:陈磊 NoSQL是现在互联网Web2.0时代备受 ... -
嵌入式数据库系统Berkeley DB
2012-08-27 14:37 1527前言 UNIX/LINUX平台下的数据库种类非常多 ... -
C语言中标准输入流、标准输出流、标准错误输出流
2011-06-13 14:32 9278C语言中标准输入流、标准输出流、标准错误输出流 在 ... -
Rsync 实现原理
2011-05-12 20:06 8314Rsync 实现原理 前言 关于rsync的原始文档 ... -
c++简单的虚函数测试
2011-04-27 14:25 1013#include <iostream> u ... -
C++文件行查找
2011-04-26 14:10 1399#include <iostream> # ... -
c++偏特化简单示例
2011-04-13 11:17 2151c++偏特化 // temp1.c ... -
GDB调试精粹及使用实例
2011-03-16 14:06 1134GDB调试精粹及使用实例 一:列文件清单 1. ... -
简单的ini文件解析
2011-02-12 16:36 1612int GetKeyVal(const string s ... -
scanf族函数高级用法
2011-01-25 16:00 2551如何解释 fscanf(fd,&quo ... -
使用scons替代makefile(1)
2011-01-25 11:58 3723早在多年前我刚开始接触linux下的C程序时,经常被makef ... -
使用scons替代makefile(2)
2011-01-25 11:57 3576本篇文章接着上一篇进一步介绍scons的使用方法,主要介绍静态 ... -
使用scons替代makefile(3)
2011-01-25 11:55 4818在上两篇文章中已经简单介绍了用scons编译库文件,可执行程序 ... -
C 支持动态添加测试数据的测试代码
2011-01-13 17:22 1114/下面的定义为了支持可扩增。 //当需要增加一个新的测试用列 ... -
Linux下Makefile的automake生成
2010-12-28 16:55 1094******************helloworld.c* ... -
SCons笔记(详细版)
2010-12-23 16:11 104991. 基本使用 SConstruct文件就功能而言相当于Ma ... -
scons 学习
2010-12-23 11:14 2176scons 学习 作者:Sam(甄峰) sam_code@h ... -
scons随笔
2010-12-22 20:20 4701scons随笔 Scons是新一代的软件构件工具,或者说ma ... -
Scons在linux下的安装和使用
2010-12-21 11:59 3277因为正在用的一个开源软件需要的Developm ... -
排列组合的实现
2010-12-20 12:41 1056简单算法: 从前往后(或者从后往前)每次交换一个位置。当存在 ...
相关推荐
字节顺序转换主要用于网络编程中,特别是当需要在网络上发送或者接收数据时。例如: 1. **IP地址的处理**:在处理IP地址时,通常需要将其从网络字节顺序转换为主机字节顺序以便于显示或进一步处理。 2. **端口的...
反向操作,即从字节数组恢复`LongInt`,则需要按照字节顺序重新组合这4个字节,再解析为整数。 其次,`Float`是单精度浮点数,它在内存中占据4个字节,包含一个符号位、8位指数和23位小数部分。转换`Float`到字节...
在计算机网络中,数据传输涉及一个关键的概念:字节序,即字节在网络中的顺序。字节序分为两种类型:大端字节序(Big-Endian)和小端字节序(Little-Endian)。理解这两种字节序对于进行跨平台的网络通信至关重要,...
这些函数可以将主机字节顺序转换为网络字节顺序,或者将网络字节顺序转换为主机字节顺序。 htonl() 函数将主机的无符号长整形数转换成网络字节顺序。ntohl() 函数将一个无符号长整形数从网络字节顺序转换为主机字节...
这些函数可以将Unsigned Short 和 Unsigned Long 类型的数据从主机序转换到网络序或从网络序转换到主机序。 在使用 Little Endian 的系统中,这些函数会把字节序进行转换,而在使用 Big Endian 的系统中,这些函数...
- `htonl(unsigned long hostLong)`:将主机字节序的32位整数转换为网络字节序。 - `ntohs(unsigned short netShort)`:将网络字节序的16位整数转换为主机字节序。 - `ntohl(unsigned long netLong)`:将网络字节序...
字节序,又称为字节顺序或字节排列方式,指的是在计算机内存中或网络传输过程中多字节数据的存储顺序。简单来说,它定义了多字节数据中各个字节如何按顺序排列。在实际编程工作中,尽管很多时候开发者可能不会直接...
本文将深入探讨如何在Java中将byte数组与其他基本类型(如short、int、long)进行转换,这些转换在处理二进制数据、网络通信或序列化等方面至关重要。 首先,我们来看byte数组与short之间的转换。在Java中,byte...
在跨平台的网络编程中,字节序转换函数如htonl(主机到网络字节序,long)、ntohl(网络到主机字节序,long)、htons(主机到网络字节序,short)和ntohs(网络到主机字节序,short)非常常见,它们确保数据在网络上...
- `htonl()`:将主机字节顺序的long整数转换为网络字节顺序。 - `ntohs()`:将网络字节顺序的short整数转换为主机字节顺序。 - `ntohl()`:将网络字节顺序的long整数转换为主机字节顺序。 五、IP地址转换函数 1...
因此,从`byte[]`转换到`int`,我们需要确保数组长度至少为4,并按照字节顺序(通常为大端或小端)正确组合字节。这里我们假设默认的大端序: ```java public static int bytesToInt(byte[] bytes) { return ...
例如,`htons()`、`htonl()`、`ntohs()` 和 `ntohl()` 分别用于将短整型(short)、无符号短整型(unsigned short)、长整型(long)和无符号长整型(unsigned long)从主机字节顺序转换为网络字节顺序,以及反向...
高低字节交换(Byte Swapping),又称为字节翻转,是一种处理字节顺序的技术,主要用于解决大端字节序和小端字节序之间的转换问题。大端字节序是指数据的最高有效字节存储在最低地址,而小端字节序则相反,最低有效...
这个数字是由IPv4的四个八位字节按照从左到右的顺序转换得到的,每个字节被转换为十进制表示,并用点号分隔。这个转换过程称为“点分十进制”到“网络字节序”的转换。 转换过程如下: 1. 将 "192" 转换为十进制 ...
在Java中,这种转换尤为常见,特别是涉及到网络字节序时,因为网络字节序是TCP/IP协议栈规定的标准字节顺序,通常为大端字节序(Big-Endian)。 上述代码片段提供了一些在Java中实现整型数(long类型)与网络字节序...
理解这些基本的数据结构和字节顺序转换函数是学习socket编程的关键。通过它们,我们可以创建、绑定、监听和接受来自网络的连接,进而实现跨机器的通信。当编写跨平台的网络应用程序时,正确处理字节顺序尤为重要,...
2. **字节序**:计算机存储数据时,多字节类型(如整数、浮点数)的字节顺序有两种主要方式,即大端序(Big-Endian)和小端序(Little-Endian)。大端序是指最高位的字节存储在内存地址的低位,而小端序则相反,最低...
- 将`byte[]`转换回`int`或`Long`,需要按照正确的顺序组合字节,可能还需要考虑字节序(Big-Endian或Little-Endian)。 - 使用位移操作将每个字节的值移到适当位置,然后通过逻辑或运算(`|`)组合成原始数值。 ...
1. htonl():这是Host to Network Long的缩写,用于将主机上的32位无符号整数(long)转换为网络字节顺序。在Windows中,它包含在头文件中;而在Linux中,它位于头文件中。例如,在发送一个结构体如`STU`时,其中的...