ipv6练手及大小端相关测试

本文介绍了一种在C++中实现IPv4和IPv6地址相互转换的方法,并提供了详细的源代码示例。通过定义IPv4v6结构体,支持不同类型的IP地址存储与转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里直接贴出源码,需要的朋友可以直接copy运行(gcc版本须大于等于4.8.5)

#include <endian.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/time.h>

#include <iostream>
#include <queue>
#include <string>
#include <vector>
#include <array>
#include <bitset>
#include <memory>
#include <functional>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <cstdlib>
#include <cmath>
#include <algorithm>

struct uint64IPv6
{
	uint64_t ipv6_Ip_1;
	uint64_t ipv6_Ip_2;

	uint64IPv6() :ipv6_Ip_1(0), ipv6_Ip_2(0){}
	void operator= (const uint64IPv6 &key)
	{
		this->ipv6_Ip_1 = key.ipv6_Ip_1;
		this->ipv6_Ip_2 = key.ipv6_Ip_2;
	}
	void operator() (const uint64IPv6 &key)
	{
		this->ipv6_Ip_1 = key.ipv6_Ip_1;
		this->ipv6_Ip_2 = key.ipv6_Ip_2;
	}
};

struct IPv4v6
{
	uint8_t v6_v4;//0=v4,1=v6
	union
	{
		//v6_v4 = 0(ipv4)存储
		uint32_t ipv4;
		//v6_v4 = 1(ipv6)存储
		uint64IPv6 ipv6_64;
		struct in6_addr ipv6_addr;
	};

	//ipFlag : 0=v4, 1=v6
	IPv4v6(uint8_t ipFlag):v6_v4(ipFlag){}
	IPv4v6(const IPv4v6& src)
	{
		ipv6_64.ipv6_Ip_1 = src.ipv6_64.ipv6_Ip_1;
		ipv6_64.ipv6_Ip_2 = src.ipv6_64.ipv6_Ip_2;
		v6_v4 = src.v6_v4;
	}
	IPv4v6& operator=(const IPv4v6& src)
	{
		ipv6_64.ipv6_Ip_1 = src.ipv6_64.ipv6_Ip_1;
		ipv6_64.ipv6_Ip_2 = src.ipv6_64.ipv6_Ip_2;
		v6_v4 = src.v6_v4;
		return *this;
	}
};

//retrun 失败:小于0,成功:0
int ipstr_to_v4v6(IPv4v6& addr, const char *ipstr, uint size)
{
	if (strchr(ipstr, ':') == NULL)//ipv4
	{
		if (inet_pton(AF_INET, ipstr, &(addr.ipv4)) != 1)
			return -1;
		addr.v6_v4 = 0;
	}
	else //ipv6
	{
		if (inet_pton(AF_INET6, ipstr, &(addr.ipv6_addr)) != 1)
			return -1;
		addr.v6_v4 = 1;
	}
	return 0;
}

//retrun 失败:小于0,成功:大于0
int ipv4v6_to_string(IPv4v6 addr, char *ipstr, int size)
{
	if (size < 40)
		return -1;
	if (addr.v6_v4 == 0)//ipv4
	{
		if (inet_ntop(AF_INET, &(addr.ipv4), ipstr, size) == NULL)
			return -1;
		return (int)strlen(ipstr);
	}
	else//ipv6
	{
		
		if (inet_ntop(AF_INET6, &(addr.ipv6_addr), ipstr, size) == NULL)
			return -1;
		return (int)strlen(ipstr);
	}
	return -1;
}

int main(void)
{
	std::string ipv4("192.168.21.36");
	std::string ipv6("2001:0db8:85a3:08d3:1319:8a2e:0370:7344");

	char buff[40];
	IPv4v6 a(0);
	ipstr_to_v4v6(a, ipv4.c_str(), ipv4.size());
	std::cout << a.ipv4 << std::endl;
	uint32_t *b = &a.ipv4;
	printf("%0x\n", *((uint8_t *)(b)));
	printf("%0x\n", *((uint8_t *)(b) + 1));
	printf("%0x\n", *((uint8_t *)(b) + 2));
	printf("%0x\n", *((uint8_t *)(b) + 3));
	std::cout << "========================" << std::endl;
	std::bitset<8> n(*((uint8_t *)(b)));
	for (int i = 0; i < 8; i++)
	{
		std::cout << n[i] << std::endl;
	}
	
	std::cout << "========================" << std::endl;
	uint32_t m = be32toh(a.ipv4);
	std::cout << m << std::endl;
	b = &m;
	printf("%0x\n", *((uint8_t *)(b)));
	printf("%0x\n", *((uint8_t *)(b) + 1));
	printf("%0x\n", *((uint8_t *)(b) + 2));
	printf("%0x\n", *((uint8_t *)(b) + 3));

	memset(buff, 0, sizeof(buff));
	ipv4v6_to_string(a, buff, sizeof(buff));
	std::cout << buff << std::endl;
	std::cout << "++++++++++++++++++++++++++++++++++++++" << std::endl;

	ipstr_to_v4v6(a, ipv6.c_str(), ipv6.size());
	printf("%0x\n", a.ipv6_addr.s6_addr[0]);
	printf("%0x\n", a.ipv6_addr.s6_addr[1]);
	printf("%0x\n", a.ipv6_addr.s6_addr[2]);
	printf("%0x\n", a.ipv6_addr.s6_addr[3]);
	printf("%0x\n", a.ipv6_addr.s6_addr[4]);
	printf("%0x\n", a.ipv6_addr.s6_addr[5]);
	printf("%0x\n", a.ipv6_addr.s6_addr[6]);
	printf("%0x\n", a.ipv6_addr.s6_addr[7]);
	printf("%0x\n", a.ipv6_addr.s6_addr[8]);
	printf("%0x\n", a.ipv6_addr.s6_addr[9]);
	printf("%0x\n", a.ipv6_addr.s6_addr[10]);
	printf("%0x\n", a.ipv6_addr.s6_addr[11]);
	printf("%0x\n", a.ipv6_addr.s6_addr[12]);
	printf("%0x\n", a.ipv6_addr.s6_addr[13]);
	printf("%0x\n", a.ipv6_addr.s6_addr[14]);
	printf("%0x\n", a.ipv6_addr.s6_addr[15]);
	std::cout << "------------------------------------" << std::endl;
	printf("%0x\n", a.ipv6_addr.s6_addr32[0]);
	printf("%0x\n", a.ipv6_addr.s6_addr32[1]);
	printf("%0x\n", a.ipv6_addr.s6_addr32[2]);
	printf("%0x\n", a.ipv6_addr.s6_addr32[3]);
	std::cout << "------------------------------------" << std::endl;
	printf("%0lx\n", a.ipv6_64.ipv6_Ip_1);
	printf("%0lx\n", a.ipv6_64.ipv6_Ip_2);

	memset(buff, 0, sizeof(buff));
	ipv4v6_to_string(a, buff, sizeof(buff));
	std::cout << buff << std::endl;
 
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值