既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
- uint16_t ntohs(uint16_t):用于将按网络字节序存储的16位整数转化为本机字节序;
- uint32_t htonl(uint32_t):用于将按本机字节序存储的32位整数转化为网络字节序;
- uint32_t ntohl(uint32_t):用于将按网络字节序存储的32位整数转化为本机字节序;
以上四个函数名中,h,n,s,l
分别代表主机,网络,短整数,长整数。前两个函数在网络编程中常用于转换端口号,后面个则是用于转换ipv4地址。
通过字节转换函数我们就可以在字节大小端之间根据需要进行转换。
比特序大小端
字节序是一个对象中的多个字节之间的顺序问题,比特序就是一个字节中的8个比特位(bit)之间的顺序问题。一般情况下系统的比特序和字节序是保持一致的。一个字节由8个bit组成,这8个bit也存在如何排序的情况,跟字节序类似的有最高有效比特位、最低有效比特位。比特序(LSB)1 0 0 1 0 0 1 0(MSB)在大端系统中最高有效比特位为1、最低有效比特位为0,字节的值为0x92。在小端系统中最高、最低有效比特位则相反为0、1,字节的值为0x49。跟字节序类似,要想保持一个字节值不变那么就要使系统能正确的识别最高、最低有效比特位。
- 比特序小端:将最高有效比特位放在了bit0,将最低有效比特位放在了bit7;
- 比特序大端:将最高有效比特位放在了bit7,将最低有效比特位放在了bit0;
通过上图我们知道 字节地址顺序和比特顺序是不变的,大小端的不同在于机器怎么对这些地址空间进行填充。
我们可以将字节地址顺序和比特顺序看作是硬件性质。
字节序转换后我在想是不是比特序也一同进行了转换?
为什么会有这个疑问呢,因为前文可知系统的比特序和字节序是一致的,现在字节序已经从小端变成了大端那么比特序应该也要一起转换。而且如果比特序不变化那么当这些字节到了目标大端序系统中后每一个字节的值都会发生变化,因为同样的比特序列在小端和大端系统中识别的字节值会不一样。
首先从htonl、ntohl的源码来看确实只进行了字节序的转换并没有进行比特序的转换,再有就是以前socket编程的时候只调用了ntohl、htonl等函数并没有调用(而且系统也没有提供)比特序转换函数,但是最后的结果都是正确的,并没有发现上面提到的字节值发生变化的问题。
那么这个”神奇”的事情是怎么解决的呢,好像系统本身就给我们”悄悄”的解决了我担心的问题。
比特(bit)的发送和接收顺序
比特的发送、接收顺序是指一个字节中的bit在网络电缆中是如何发送、接收的。在以太网(Ethernet)中,是从最低有效比特位到最高有效比特位的发送顺序,也就是最低有效比特位首先发送,参考资料:frame。
在以太网中这个规定有点奇怪,因为字节序我们是按照大端序来发送,但是比特序却是按照小端序的方式来发送,下图是直接从网上找来的一张图,主机序本身是大端序
比特的发送、接收顺序对CPU、软件都是不可见的,因为我们的网卡会给我们处理这种转换,在发送的时候按照小端序发送比特位,在接收的时候会把接收到的比特序转换成主机的比特序,下面是一个小端机器发送一个int整型给一个大端机器的示意图:
- htonl、ntohl函数肯定是不会同步转换一个字节中的比特序的,因为如果比特序也发生了转换的话那么这个字节的值也就发生了变化,记住htonl、ntohl只是字节序转换函数。
- 比特序按照小端的方式发送,首先发送的是最低有效比特位,最后发送的是最高有效比特位,接收端的网卡在接收到比特序列后按照主机的比特序把接收到的”小端序”比特流转换成主机对应的比特序列。
- 可以假设存在ntohb、htonb(b代表bit)这样的两个函数,网卡进行了比特序的转换,不过是这两个函数是网卡自动调用的,我们平时不用关注。
按照规则,发送、接收的时候进行比特序的转换,那么就能保证在不同的机器之间进行通信不会发生我担心的字节值发生变化的问题。
大小端转换综合应用
现在假设两种应用场景:
- 大端机器接收来自小端机器的数据,在此过程中我们不做任何处理,看看应该怎么使用这个数据。
- 小端机器接收来自大端机器的数据,在此过程中我们不做任何处理,看看应该怎么使用这个数据。
大端机器接收来自小端机器的数据
假设下图是来自小端机器的数据,现在原封不动的传入到大端机器中
大端机器其实会将上图数据解释成
如果我们传输的这个4个字节的数据包含一定含义,那么在大端机器上,我们要怎么还原出这个含义呢?
假设这4个字节在原来小段机器上的含义如下图
字节0x0000是一个位域
字节0x0001也是一个位域
字节0x0002和字节0x0003代表一个short整型数据的两个字节。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
dn.net/topics/618658159)**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!