用uint64来表示IP+Port

xiaoxiao2025-07-23  25

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表示形式

转载请注明原文地址: https://www.6miu.com/read-5033582.html

最新回复(0)