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位
uint16_t htons(uint16_t hostint16);//16位

功能:

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

参数:

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

返回值:

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


#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;

}

运行结果如下:
在这里插入图片描述

const char *inet_ntop( int family, const void *addrptr,  char *strptr, size_t len );

功能:

将 32 位无符号整数转换成点分十进制数串

参数:

1、 family:协议族( AF_INET、AF_INET6、PF_PACKET 等 ),常用 AF_INET
2、addrptr:32 位无符号整数
3、strptr:点分十进制数串
4、len:strptr 缓存区长度
len 的宏定义
#define INET_ADDRSTRLEN 16 // for ipv4
#define INET6_ADDRSTRLEN 46 // for ipv6

返回值:

成功:则返回字符串的首地址
失败:返回 NULL

测试示例:


#include <stdio.h>
#include <arpa/inet.h>

int main()
{

	unsigned char ip[] = {172,20,223,75};
	char ip_str[16] = "NULL";

	inet_ntop(AF_INET,(unsigned int *)ip,ip_str,16);
	printf("ip_str = %s\n",ip_str);

	return 0;

}

在这里插入图片描述

地址转换函数

以下接口所需头文件:#include <arpa/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr);

功能:

将点分十进制数串转换成 32 位无符号整数

参数:

family:协议族( AF_INET、AF_INET6、PF_PACKET 等 ),常用 AF_INET
strptr:点分十进制数串
addrptr:32 位无符号整数的地址

返回值:

成功返回 1 、 失败返回其它


#include <stdio.h>
#include <arpa/inet.h>

int main()
{
	char ip_str[]="172.20.223.75";
	unsigned int ip_uint = 0;
	unsigned char *ip_p = NULL;


	inet_pton(AF_INET,ip_str,&ip_uint);

	printf("in_uint = %d\n",ip_uint);
	ip_p = (char *)&ip_uint;
	printf("in_uint = %d,%d,%d,%d\n",*ip_p,*(ip_p+1),*(ip_p+2),*(ip_p+3));

	return 0;

}

在这里插入图片描述
本文学习资料来自于(https://blog.csdn.net/tennysonsky/article/details/45045549

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值