用uint64来表示IP+Port

5 篇文章 0 订阅
4 篇文章 0 订阅

uint64_t

这是uint64在<stdint.h>(/usr/include/stdint.h)中的定义

/* Unsigned.  */
typedef unsigned char           uint8_t;
typedef unsigned short int      uint16_t;
#ifndef __uint32_t_defined
typedef unsigned int            uint32_t;
# define __uint32_t_defined
#endif
#if __WORDSIZE == 64
typedef unsigned long int       uint64_t;
#else
__extension__
typedef unsigned long long int  uint64_t;
#endif

uint64_t在64位环境中表示unsigned long int,无符号长整型。

u表示unsigned,64、32、16、8表示位数,其中uint8_t比较特殊,虽然写了int,但是uint8_t表示的是无符号char(一个char在内存中占用1字节,即8位)


用uint64_t来表示IP+Port

在一些场景中,需要对IP+Port表示的一个节点进行判重,即全局的IP+Port要保持唯一,可以通过位运算将IP+Port转为uint64_t格式并存储。

将IP和Port转为uint64_t

uint64_t HostToUint(const char *ip, uint16_t port){
	in_addr_t addr = inet_addr(ip);		//typedef uint32_t in_addr_t;

	uint64_t res = 0;
	//通过位运算将IP和Port拼接成一个uint64_t
	res = ((uint64_t)addr << 16) | (uint64_t)(port);
	
	return res;	//res即为uint64_t格式的IP+Port
}

通过man命令查看inet_addr

man inet_addr
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
in_addr_t inet_addr(const char *cp);
/**
The inet_addr() function converts the Internet host address cp from IPv4
 numbers-and-dots notation into binary data in network byte  order.   
 If the input is invalid, INADDR_NONE (usually -1) is returned. 
 Use of this function is problematic because -1 is a valid address (255.255.255.255).  
 Avoid its use in favor of inet_aton(), inet_pton(3), or getaddrinfo(3)
  which provide a cleaner way to indicate error return.
**/

即inet_addr()可以将IPv4数字和点格式的地址转换成网络字节序。


将uint64_t转为IP和Port

同样的,再对uint64_t的值进行位运算,可以拆分出ip和port

int Uint64ToHost(uint64_t src, uint16_t *port, char* dstIP, size_t desIPsz){
    uint32_t ip = (uint32_t)((src & 0xffffffffffff0000u) >> 16);
    uint16_t tmpPort = (uint16_t)(src & 0x000000000000ffffu);

    *port = (tmpPort);

    if(inet_ntop(AF_INET, &ip, dstIP, desIPsz) == NULL){
            return -1;
    }else{
            return 0;
    }
}

同样可以用man inet_ntop来查看inet_ntop的帮助信息

#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

完整测试代码如下:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <iostream>
#include <cstdint>

using namespace std;

uint64_t HostToUint(const char *ip, uint16_t port){
    in_addr_t addr = inet_addr(ip);         //typedef uint32_t in_addr_t;

    uint64_t res = 0;
    res = ((uint64_t)addr << 16) | (uint64_t)(port); 

    return res;
}

int Uint64ToHost(uint64_t src, uint16_t *port, char* dstIP, size_t desIPsz){
    uint32_t ip = (uint32_t)((src & 0xffffffffffff0000u) >> 16);
    uint16_t tmpPort = (uint16_t)(src & 0x000000000000ffffu);

    *port = (tmpPort);

    if(inet_ntop(AF_INET, &ip, dstIP, desIPsz) == NULL){
            return -1;
    }else{
            return 0;
    }
}


int main(int argc, char** agrv){
    const char ip[] = "192.168.11.234";
    uint16_t port = 12134;
    uint64_t res = HostToUint(ip, port);

    cout << res << endl;
    //res = 257335796707174
    char dstIP[17] = "";
    uint16_t dstPort = 0;
    Uint64ToHost(res, &dstPort, dstIP, sizeof(dstIP));
    cout << dstIP << ":" << dstPort << endl;

    return 0;
}

运行结果:
在这里插入图片描述
257335796707174即192.168.11.234:12134的uint64_t表示形式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值