Linux 网络编程——网络字节序、地址转换

字节序

字节序是指多字节数据的存储顺序,在设计计算机系统的时候,有两种处理内存中数据的方法:大端格式、小端格式。

小端格式(Little-Endian):将低位字节数据存储在低地址。
大端格式(Big-Endian):将高位字节数据存储在低地址。

举个简单的例子,对于整形 0x12345678,它在大端格式和小端格式的系统中,分别如下图所示的方式存放:

下面例子为确定主机的字节序:

#include <stdio.h>
 
int main(int argc, char *argv[])
{
	unsigned int a = 0x12345678;
	unsigned char *p = (unsigned char *)&a;	//只取一个字节
	if(0x12 == *p)
	{
		printf("Big-Endian\n");
	}
	else if(0x78 == *p)
	{
		printf("Little-Endian\n");
	}
	return 0;
}

网络上的数据流是字节流,对于一个多字节数值,在进行网络传输的时候,先传递哪个字节?也就是说,当接收端收到第一个字节的时候,它是将这个字节作为高位还是低位来处理呢?

网络字节序定义:收到的第一个字节被当作高位看待,这就要求发送端发送的第一个字节应当是高位。而在发送端发送数据时,发送的第一个字节是该数字在内存中起始地址对应的字节。可见多字节数值在发送前,在内存中数值应该以大端法存放。

所以,网络协议指定了通讯字节序:大端。只有在多字节数据处理时才需要考虑字节序,运行在同一台计算机上的进程相互通信时,一般不用考虑字节序,异构计算机之间通讯,需要转换自己的字节序为网络字节序。
字节序转换函数介绍

以下接口所需头文件:#include <arpa/inet.h>

uint32_t htonl(uint32_t hostint32);

功能:

将 32 位主机字节序数据转换成网络字节序数据

参数:

hostint32:需要转换的 32 位主机字节序数据,uint32_t 为 32 为无符号整型

返回值:

成功:返回网络字节序的值

uint16_t htons(uint16_t hostint16);

功能:

将 16 位主机字节序数据转换成网络字节序数据

参数:

hostint16:需要转换的 16 位主机字节序数据,uint16_t,unsigned short int

返回值:

成功:返回网络字节序的值

#include <stdio.h>
#include <arpa/inet.h>
 
int main(int argc, char *argv[])
{
	int a = 0x01020304;
	short int b = 0x0102;
	
	printf("htonl(0x%08x) = 0x%08x\n", a, htonl(a));
	printf("htons(0x%04x) = 0x%04x\n", b, htons(b));
	
	return 0;
}

运行结果

samba@ubuntu64:~/share/net$ ./a.out 
htonl(0x01020304) = 0x04030201
htons(0x0102) = 0x0201

猜你喜欢

转载自blog.csdn.net/lqf_ok/article/details/87620413