项目中遇到很多种类型主机序和网络序互转的情况,通过下面样例,对不同的情况进行代码实现。本文只介绍转换方法,不介绍网络序和主机序的区别。
情景一:网络字节序转主机序
解析处理网络数据报文时,经常遇到将解析出的IP
地址或者PORT
等信息保存下来,此时部分需求是保存为主机序列,部分要求为网络序(进行二次匹配查询时不必再次转换)
无符号整型数字网络序转主机序代码如下:
#include <stdio.h>
#include <arpa/inet.h>
#define NET_NUM 123
int main(void)
{
// 1字节数字转换(不用转换)
uint8_t num0 = NET_NUM;
printf("num0 = %u\n", num0);
// 2字节数字转换
uint16_t num1 = ntohs(NET_NUM);
printf("num1 = %u\n", num1);
// 4字节数字转换
uint32_t num2 = ntohl(NET_NUM);
printf("num2 = %u\n", num2);
// 8字节数字转换
uint64_t num3 = be64toh(NET_NUM);
printf("num3 = %lu\n", num3);
return 0;
}
情景二:主机序转网络字节序
有时候通过socket
发送数据时,需要先将数据格式化为网络字节序,因此会用到。
无符号整型数字主机序转网络序代码如下:
#include <stdio.h>
#include <arpa/inet.h>
#define HOST_NUM 123
int main(void)
{
// 1字节数字转换(不用转换)
uint8_t num0 = HOST_NUM;
printf("num0 = %u\n", num0);
// 2字节数字转换
uint16_t num1 = htons(HOST_NUM);
printf("num1 = %u\n", num1);
// 4字节数字转换
uint32_t num2 = htonl(HOST_NUM);
printf("num2 = %u\n", num2);
// 8字节数字转换
uint64_t num3 = htobe64(HOST_NUM);
printf("num3 = %lu\n", num3);
return 0;
}
情景三:IP地址互相之间的转换
IPV4
占用大小为4
字节,IPV6
占用大小为16
字节,IP
地址互相转换代码如下:
#include <stdio.h>
#include <arpa/inet.h>
// IPv4
static void ipv4_tp(char *Ipv4){
uint32_t net_ipv4, host_ipv4;
char strIpv4[16] = {0};
// 点分十制转网络序
inet_pton(AF_INET, Ipv4, &net_ipv4);
printf("net_ipv4 = %u\n", net_ipv4);
// 网络序转主机序
host_ipv4 = ntohl(net_ipv4);
printf("host_ipv4 = %u\n", host_ipv4);
// 主机序转网络序
net_ipv4 = htoln(host_ipv4);
printf("net_ipv4 = %u\n", net_ipv4);
// 网络序转点分制
inet_ntop(AF_INET, &net_ipv4, strIpv4, INET_ADDRSTRLEN);
printf("strIpv4 = %s\n", strIpv4);
return;
}
// IPv6
static void ipv6_tp(char *Ipv6){
uint32_t net_ipv6[4], host_ipv6[4];
char strIpv6[64] = {0};
// 点分十六制转网络序
inet_pton(AF_INET6, Ipv6, net_ipv6);
for(int i = 0; i < 4; i++){
printf("net_ipv6[%d] = %u", i, net_ipv6[i]);
if(i != 3) printf(" "); else printf("\n");
}
// 网络序转主机序
for(int i = 0; i < 4; i++){
host_ipv6[i] = ntohl(net_ipv6[i]);
}
for(int i = 0; i < 4; i++){
printf("host_ipv6[%d] = %u", i, host_ipv6[i]);
if(i != 3) printf(" "); else printf("\n");
}
// 主机序转网络序
for(int i = 0; i < 4; i++){
net_ipv6[i] = ntohl(host_ipv6[i]);
}
for(int i = 0; i < 4; i++){
printf("net_ipv6[%d] = %u", i, net_ipv6[i]);
if(i != 3) printf(" "); else printf("\n");
}
// 网络序转点分制
inet_ntop(AF_INET6, net_ipv6, strIpv6, INET6_ADDRSTRLEN);
printf("strIpv6 = %s\n", strIpv6);
return;
}
int main(void)
{
char strIpv4[16] = {"192.168.1.1"};
char strIPV6[64] = {"fe80::20c:29ff:fe3b:846f"};
ipv4_tp(strIpv4);
ipv6_tp(strIPV6);
return 0;
}
未完待续~