【网络篇】第四篇——网络字节序
网络字节序和本机转换
字节序转换函数
网络字节序和本机转换
计算机在存储数据时是有大小端的概念的:
- 大端模式: 数据的高字节内容保存在内存的低地址处,数据的低字节内容保存在内存的高地址处。
- 小端模式: 数据的高字节内容保存在内存的高地址处,数据的低字节内容保存在内存的低地址处。
如果编写的程序只在本地机器上运行,那么是不需要考虑大小端问题的,因为同一台机器上的数据采用的存储方式都是一样的,要么采用的都是大端存储模式,要么采用的都是小端存储模式。但如果涉及网络通信,那就必须考虑大小端的问题,否则对端主机识别出来的数据可能与发送端想要发送的数据是不一致的。
例如,现在两台主机之间在进行网络通信,其中发送端是小端机,而接收端是大端机。发送端将发送缓冲区中的数据按内存地址从低到高的顺序发出后,接收端从网络中获取数据依次保存在接收缓冲区时,也是按内存地址从低到高的顺序保存的。
但由于发送端和接收端采用的分别是小端存储和大端存储,此时对于内存地址从低到高为44332211的序列,发送端按小端的方式识别出来是0x11223344,而接收端按大端的方式识别出来是0x44332211,此时接收端识别到的数据与发送端原本想要发送的数据就不一样了,这就是由于大小端的偏差导致数据识别出现了错误。
由于我们不能保证通信双方存储数据的方式是一样的,因此网络当中传输的数据必须考虑大小端问题。因此TCP/IP协议规定,网络数据流采用大端字节序,即低地址高字节。无论是大端机还是小端机,都必须按照TCP/IP协议规定的网络字节序来发送和接收数据。
- 如果发送端是小端,需要先将数据转成大端,然后再发送到网络当中。
- 如果发送端是大端,则可以直接进行发送。
- 如果接收端是小端,需要先将接收到数据转成大端后再进行数据识别。
- 如果接收端是大端,则可以直接进行数据识别。
在这个例子中,由于发送端是小端机,因此在发送数据前需要先将数据转成大端,然后再发送到网络当中,而由于接收端是大端机,因此接收端接收到数据后可以直接进行数据识别,此时接收端识别出来的数据就与发送端原本想要发送的数据相同了。
需要注意的是,所有的大小端的转化工作是由操作系统来完成的,因为该操作属于通信细节,不过也有部分的信息需要我们自行进行处理,比如端口号和IP地址。
如何证明自己的机器采用了哪种字节顺序:
/* 确定你的电脑是大端字节序还是小端字节序 */
#include <stdio.h>int check1()
{int i = 1; //1在内存中的表示: 0x00000001char *pi = (char *)&i; //将int型的地址强制转换为char型return *pi == 0; //如果读取到的第一个字节为1,则为小端法,为0,则为大端法
}int main()
{if (check1() == 1)printf("big\n");elseprintf("little\n");return 0;
}第二种方法,我们用联合结构解决,其本质差异不大
/* 确定你的电脑是大端字节序还是小端字节序 */
#include <stdio.h>int check2()
{union test {char ch;int i;}test0;test0.i = 1;return test0.ch == 0;
}
int main()
{if (check1() == 1)printf("big\n");elseprintf("little\n");return 0;
}
为什么网络字节序采用的是大端?而不是小端?
网络字节序采用的是大端,而主机字节序一般采用的是小端,那为什么网络字节序不采用小端呢?如果网络字节序采用小端的话,发送端和接收端在发生和接收数据时就不用进行大小端的转换了。
该问题有很多不同说法,下面列举了两种说法:
- 说法一: TCP在Unix时代就有了,以前Unix机器都是大端机,因此网络字节序也就采用的是大端,但之后人们发现用小端能简化硬件设计,所以现在主流的都是小端机,但协议已经不好改了。
- 说法二: 大端序更符合现代人的读写习惯。
字节序转换函数
为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,系统提供了四个函数,可以通过调用以下库函数实现网络字节序和主机字节序之间的转换。
#include <arpa/inet.h>//将主机字节序转换为网络字节序unit32_t htonl (unit32_t hostlong);unit16_t htons (unit16_t hostshort);//将网络字节序转换为主机字节序unit32_t ntohl (unit32_t netlong);unit16_t ntohs (unit16_t netshort);说明:h -----host;n----network ;s------short;l----long。
htons()--"Host to Network Short"
htonl()--"Host to Network Long"
ntohs()--"Network to Host Short"
ntohl()--"Network to Host Long"
- 函数名当中的h表示host,n表示network,l表示32位长整数,s表示16位短整数。
- 例如htonl表示将32位长整数从主机字节序转换为网络字节序。
- 如果主机是小端字节序,则这些函数将参数做相应的大小端转换然后返回。
- 如果主机是大端字节序,则这些函数不做任何转换,将参数原封不动地返回。
【网络篇】第四篇——网络字节序相关推荐
- 【Linux从青铜到王者】第二十三篇:Linux网络基础第四篇之kcp协议
系列文章目录 文章目录 系列文章目录 前言 一.kcp协议简介 二.kcp技术特性 1.RTO翻倍vs不翻倍 2.选择性重传 vs 全部重传 3.快速重传 4.延迟ACK vs 非延迟ACK 5.UN ...
- python学习之路基础篇(第四篇)
一.课程内容回顾 1.python基础 2.基本数据类型 (str|list|dict|tuple) 3.将字符串"老男人"转换成utf-8 s = "老男人" ...
- 本地字节序与网络字节序的相互转换(IP地址、端口号)
一般数据在内存中是按照字节存储的,存储的方式分为大端和小端.在不知道对方主机的存储方式的情况下,我们不知道是否需要转换数据的存储方式.因此,TCP/IP协议规定:发送到网络的数据流应采用大端字节序! ...
- linux c 客户端与 golang 服务端通信(网络字节序)
网络二进制数据转换: 总所周知,数据在tcp网络传输协议中传输的字节序是大端模式的,换句话说如果你要传输一个int32型的整数,那么假设其二进制小端模式表示为111111111111111100000 ...
- 用 Python 写网络编程(四)
本文首发于TesterHome社区,作者是资深游戏测试开发工程师陈子昂.用 Python 写网络编程共四篇,今天分享的是第四篇.原文链接:https://testerhome.com/topics/2 ...
- 最简单人工智能python_Python人工智能之路 - 第四篇 : jieba gensim 最好别分家之最简单的相似度实现...
简单的问答已经实现了,那么问题也跟着出现了,我不能确定问题一定是"你叫什么名字",也有可能是"你是谁","你叫啥"之类的,这就引出了人工智能 ...
- 查看此docker网络连接模式_Docker 网络模式(四种)详细介绍
Docker 网络模式 本文首先介绍了Docker自身的4种网络工作方式, Docker作为目前最火的轻量级容器技术,有很多令人称道的功能,如Docker的镜像管理.然而,Docker同样有着很多不完 ...
- Vue 生命周期探索:第四篇:生命周期-销毁流程
文章目录 探索学习 Vue 生命周期篇 第四篇:生命周期-销毁流程 生命周期_销毁流程 1. beforeDestory (销毁前) 2. Teardown watchers,child compon ...
- 字节序: 一个不是很重要的概念
字节序 我们将一个4字节的汉字存入一段4字节的物理容器里, 该怎么存放? 直觉都是从左往右依次写入, 但也可以从右向左写, 甚至可以先写入奇字节再写偶字节, 这样比划下可以有n!种存储方式(n是字节数 ...
- 13. 一步一图带你深入剖析 JDK NIO ByteBuffer 在不同字节序下的设计与实现
一步一图带你深入剖析 JDK NIO ByteBuffer 在不同字节序下的设计与实现 让我们来到微观世界重新认识 Netty 在前面 Netty 源码解析系列 <聊聊 Netty 那些事儿&g ...
最新文章
- 使用axis开发web service服务端
- 《Windows驱动开发技术详解》读书笔记(一)
- Linux基础:Shell脚本学习
- SQL基本语句及用法
- boost::geometry::detail::overlay::select_rings用法的测试程序
- C#XmlDocument无法读取utf-16文件
- ubuntu mysql5.7配置_ubuntu系统mysql5.7忘记/设置root的坑
- POI Excel解析
- 使用 TensorFlow 构建机器学习项目中文版
- 《张宇考研数学基础30讲》思维导图-第2讲 数列极限
- 微信叫车系统|顺风车小程序|在线选座拼车订票APP【开发实战】
- 百度BML飞桨训练营(五)商品种类识别
- 树莓派制作无线路由器
- 补充(二)古典密码两张思维导图速通
- switch()的参数类型
- GMSK调制解调(二)
- H264码流打包成RTP包
- 软件测试项目流程报告,周口软件测试报告流程,科技项目申报
- IP地址(简单模拟)
- DEJA_VU3D - Cesium功能集 之 090-台风过境实时动画
热门文章
- Dell R720 安装 win2003 64位 的安装步骤以及注意事项
- 又双叒叕上榜|九州云入选“2022中国边缘计算企业20强”
- 599元红米狂欢背后的冷思考
- 京东小程序开放平台正式发布- 新服务!新体验!
- 内网渗透系列之mimikatz的使用以及后门植入
- CamStudio——手用得录屏软件
- Epub360教你如何制作报纸翻页式创意招聘H5?
- 我的世界手机版javaui材质包_我的世界:感受国外顶级3D材质包CreatorCraft
- 好用的外贸邮箱有哪些?公司企业邮箱申请哪个好?
- 淘宝、拼多多模式的集合体——CRMEB商城