Linux网络编程——字节序与网络字节序
说明:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
QQ 群 号:513683159 【相互学习】
内容来源:
《Linux网络编程》
内容概述:
简单介绍字节序与网络字节序的概念
两个示例:
1.检查本机字节序
2.字节序转换
字节序概念
什么是字节序?
字节序是由于不同主处理器(CPU)和操作系统(OS)对多字节的变量在内存中存放顺序的不同而产生的。
字节序的分类?一般分为两类:
①小端字节序(Little Endian,LE):变量的内存地址起始地址存放低字节,高字节顺序存放
②大端字节序(Big Endian, BE):变量的内存地址起始地址存放高字节,低字节顺序存放
实例:
示例:检查本机字节序
源代码:check_order.c
#include <stdio.h>/*** 字节序结构变量* 联合类型的变量:所有成员占用同一段内存,修改一个成员会影响其他成员。* 成员value高低端字节可由成员type按字节访问
*/
typedef union
{unsigned short int value; //短整型变量unsigned char byte[2]; //字符类型
}to;int main(int argc,char *argv[])
{/*** 变量声明与赋值* Note: value 和 byte成员共享同一块内存,* 故可通过byte的不同成员访问value的高低字节*/to typeorder;typeorder.value = 0xabcd;/*** 计算字节序结构中成员字节大小*/printf("Byte size:value = %ld,byte[0] = %ld\n",sizeof(typeorder.value),sizeof(typeorder.byte[0]));/*** 小端字节序检查* 小端字节序(LE):起始地址存放低字节,高字节顺序存放* Note:* 低字节 = byte[1]: 0xab* 高字节 = byte[0]: 0xcd */if(typeorder.byte[0] == 0xcd && typeorder.byte[1] == 0xab){printf("Low endian byte order byte[0]:0x%x,byte[1]:0x%x\n",typeorder.byte[0],typeorder.byte[1]);}/*** 大端字节序检查* 大端字节序(BE):起始地址存放高字节,低字节顺序存放* Note:* 低字节 = byte[1]: 0xcd* 高字节 = byte[0]: 0xab */if(typeorder.byte[0] == 0xab && typeorder.byte[1] == 0xcd){printf("High endian byte order byte[0]:0x%x,byte[1]:0x%x\n",typeorder.byte[0],typeorder.byte[1]);}return 0;
}
编译并运行
编译:
执行指令:gcc check_order.c -o check_order
运行:
执行指令:./check_order
结果:
Byte size:value = 2,byte[0] = 1
Low endian byte order byte[0]:0xcd,byte[1]:0xab
很明显,我的系统是小端字节序。
网络字节序概念
网络字节序:多字节变量在网络传输时的表示方法,采用的是:高端字节序。
这是由于主机千差万别,故主机字节序不能做到统一,故对于网络传输的变量必须有一个统一的表示方法。
故为程序设计方便,让程序与平台无关,可在网络传输前先对字节序进行转换。
字节序转换函数
函数位置:netinet/in.h
主机和网络字节顺序之间转换的函数,如下:
htonl()
–“Host to Network Long” —— 主机字节序到网络字节序的长整型转换
htons()
–“Host to Network Short” ——主机字节序到网络字节序的短整型转换
ntohl()
–“Network to Host Long” —— 网络字节序到主机字节序的长整型转换
ntohs()
–“Network to Host Short” —— 网络字节序到主机字节序的短整型转换
可知,函数命名规则为:字节序 to 字节序 变量类型
htonl()函数
函数功能:将主机的无符号长整形数转换成网络字节顺序。
项目 | 说明 |
---|---|
函数原型 | extern uint32_t htonl (uint32_t __hostlong) __THROW __attribute__ ((__const__)); |
头文件 | netinet/in.h |
参数说明 | __hostlong:主机字节顺序表达的32位数 |
返回值 | 返回一个网络字节顺序的值 |
注意 |
htons()函数
函数功能:将主机的无符号短整形数转换成网络字节顺序。
项目 | 说明 |
---|---|
函数原型 | extern uint16_t htons (uint16_t __hostshort) __THROW __attribute__ ((__const__)); |
头文件 | netinet/in.h |
参数说明 | __netshort:主机字节顺序表达的16位数 |
返回值 | 返回一个网络字节顺序的值。 |
注意 |
ntohl()函数
函数功能:将一个32位数由网络字节顺序转换为主机字节顺序。
项目 | 说明 |
---|---|
函数原型 | extern uint32_t ntohl (uint32_t __netlong) __THROW __attribute__ ((__const__)); |
头文件 | netinet/in.h |
参数说明 | __netlong:主机字节顺序表达的32位数 |
返回值 | 返回一个以主机字节顺序表达的数 |
注意 |
ntohs()函数
函数功能:将一个无符号短整形数从网络字节顺序转换为主机字节顺序。
项目 | 说明 |
---|---|
函数原型 | extern uint16_t ntohs (uint16_t __netshort) __THROW __attribute__ ((__const__)); |
头文件 | netinet/in.h |
参数说明 | __netshort:主机字节顺序表达的16位数 |
返回值 | 返回一个以主机字节顺序表达的数 |
注意 |
示例:字节序转换
源代码:turn_order.c
#include <stdio.h>
#include <netinet/in.h>
#define BITS16 16
#define BITS32 32/*** @union: 16位字节序结构变量* 联合类型的变量:所有成员占用同一段内存,修改一个成员会影响其他成员。* 成员value高低端字节可由成员type按字节访问
*/
typedef union
{unsigned short int value; //16位短整型变量unsigned char byte[2]; //字符类型
}to16;/*** @union: 32位字节序结构变量* 联合类型的变量:所有成员占用同一段内存,修改一个成员会影响其他成员。* 成员value高低端字节可由成员type按字节访问
*/
typedef union
{unsigned int value; //32位整型变量unsigned char byte[4]; //字符类型
}to32;/*** @function: 变量值打印函数* * @description: * 从变量存储空间的第一个字节开始,按照字节打印* * @param begin: 变量的地址指针* @param flag : 表示字长的标志变量* BITS16 :打印16位变量的值
*/
void showvalue(unsigned char *begin, int flag)
{int num = 0,i = 0;if(flag == BITS16){num = 2;}else if(flag == BITS32){num = 4; }for(i = 0;i < num; i++){printf("%x ",*(begin+i));}printf("\n");
}int main(int argc,char *argv[])
{/*** 字节序变量定义*/to16 v16_orig, v16_turn1, v16_turn2; to32 v32_orig, v32_turn1, v32_turn2;/*** 16位变量*/v16_orig.value = 0xabcd; //原始值赋值v16_turn1.value = htons(v16_orig.value); //第一次转换的值v16_turn2.value = htons(v16_turn1.value); //第二次转换的值/*** 32位变量*/v32_orig.value = 0x12345678; //原始值赋值v32_turn1.value = htonl(v32_orig.value); //第一次转换的值v32_turn2.value = htonl(v32_turn1.value); //第二次转换的值/*** 16位变量两次字节序转换结果输出:*/printf("16 host to network byte order change:\n");printf("\t orig:\t"); showvalue(v16_orig.byte,BITS16); //16位数据的原始值printf("\t 1 times:");showvalue(v16_turn1.byte,BITS16); //16位数据的第一次转换后的值printf("\t 2 times:");showvalue(v16_turn2.byte,BITS16); //16位数据的第二次转换后的值/*** 32位变量两次字节序转换结果输出:*/printf("32 host to network byte order change:\n");printf("\t orig:\t");showvalue(v32_orig.byte,BITS32); //32位数据的原始值 printf("\t 1 times:");showvalue(v32_turn1.byte,BITS32); //32位数据的第一次转换后的值printf("\t 2 times:");showvalue(v32_turn2.byte,BITS32); //32位数据的第二次转换后的值return 0;
}
编译并运行
编译:
执行指令:gcc turn_order.c -o turn_order
运行:
执行指令: ./turn_order
结果:
16 host to network byte order change:orig: cd ab 1 times:ab cd 2 times:cd ab
32 host to network byte order change:orig: 78 56 34 12 1 times:12 34 56 78 2 times:78 56 34 12
值得注意的是:
上面情形是在小端字节序系统上的结果,会发生改变。
但是在大端字节序系统上,及时调用字节序转换函数也是不会发生改变的。
Linux网络编程——字节序与网络字节序相关推荐
- linux网络编程(一)网络基础传输知识
linux网络编程(一)网络传输基础知识 一.什么是协议? 二.使用步骤 典型协议 2.网络应用程序设计模式 C/S模式 B/S模式 优缺点 3.分层模型 4.TCP/IP四层模型 通信过程 5.协议 ...
- 陈硕《网络编程实战》01 网络编程概要
陈硕<网络编程实战> 01 网络编程概要 站在巨人的肩膀之上. 按照录像整理,部分专有名词不太肯定,版权归陈硕大神. 大家好,我是陈硕,受邀讲授一门有关网络编程的在线课程,这门课程的名称是 ...
- python网络编程需要学什么,python网络编程学习笔记(五):socket的一些补充 Python 网络编程需要学习哪些网络相关的知识...
python的socket编程问题hdr = recvall(s, 5) if hdr is None: print 'Unexpected EOF receivingstruct在unpack的时候 ...
- Linux C编程--网络编程1--字节顺序和字节处理函数
字节顺序 不同的 CPU 有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序 最常见的有两种 1 . Little endian :将低序字节存储在起始地址 2 . Big ...
- 嵌入式Linux系统编程学习之三十三网络相关概念
文章目录 一.网络相关名词的概念 1.套接口 2.端口号 3.IP 地址 二.Socket 概念 三.Socket 类型 四.Socket 的信息数据结构 五.数据存储优先顺序的转换 六.地址转格式转 ...
- Linux C编程之十六 网络编程基础-socket
一.协议的概念 1. 什么是协议 从应用的角度出发,协议可理解为"规则",是数据传输和数据的解释的规则. 假设,A.B双方欲传输文件.规定: 第一次,传输文件名,接收方接收到文件名 ...
- TCP/IP网络编程:P1->理解网络编程和套接字
本系列文章为<TCP/IP网络编程----尹圣雨>学习笔记 文章目录 一.理解网络编程和套接字 1.1 构建接电话套接字 1.2 编写"Hello world!"服务器 ...
- 网络编程主机号和网络号转化
1.1. 套接口概念 套接口,也叫"套接字".是操作系统内核中的一个数据结构,它是网络中的节点进行相互通信的门户.它是网络进程的 ID.两个进程通信时,首先要确定 ...
- c语言网络编程阻塞,c语言网络编程-设置非阻塞方式
#include #include #include #include #include #include #include #include #include #include #define MA ...
- 迈入JavaWeb第一步,Java网络编程基础,TCP网络编程URL网络编程等
文章目录 网络编程概述 网络通信要素 要素一IP和端口号 要素二网络协议 TCP网络编程 UDP网络编程 URL网络编程 Java网络编程基础 网络编程概述 Java是Internet上的语言,它从语 ...
最新文章
- [转]不定义JQuery插件,不要说会JQuery
- 基于redis AE异步网络架构
- 每天一个linux命令(12):more命令
- PHP学习2——基本语法
- 【linux】kali 创建应用程序桌面图标(以burpsuite为例)
- SqlServer2008R2镜像(无域)
- 服务器是怎么工作的?(二)——arp工作原理详细解析
- 深入了解帆软报表系统的启动过程一
- Java8 - Stream API快速入门
- 优秀的程序员是这样的
- 计算机原理教程 pdf,《计算机组成原理》教程 概述.pdf
- 京东联盟API接口-单页市场-提高商品转化率-京东高级API接口
- 车辆违章查询接口文档
- 虚拟机安装linux的\/root,pt深海湛蓝爆屏图 -官网
- 教你作一份高水准的简历
- 十年后的互联网,云计算成制胜法宝
- SPSS Modeler使用之与数据库建立ODBC连接
- mcnpf5输出结果_MCNP使用说明解读.ppt
- ZStack——存储模型:主存储和备份存储
- 使用Keras进行深度学习:(一)Keras 入门