【发布时间】:2020-04-10 01:12:25
【问题描述】:
我的目标是为所有 IP 地址 - 端口对创建一个唯一 ID。跨系统的 UID 必须相同(不同字节序系统没有冲突)。 IPV4 UID 大小为 6 字节,ipv6 为 18 字节。
uint8_t sourcePair[18]; /*ipv4=(4+2) bytes or ipv6=(16+2) bytes*/
我有两个函数将获取套接字的远程端点并获取所需的 UID。设计如下。
void CmdInterpreter::makeSourcePairV4(asio::ip::tcp::endpoint& remoteEp, unsigned short portNum, unsigned char(&binSourcePair)[18])
{
auto addressClass = remoteEp.address().to_v4();
auto ipBin = addressClass.to_uint();
memcpy(&binSourcePair[0], &ipBin, 4);
memcpy(&binSourcePair[4], &portNum, 2);
}
void CmdInterpreter::makeSourcePairV6(asio::ip::tcp::endpoint& remoteEp, unsigned short portNum, unsigned char(&binSourcePair)[18])
{
auto addressClass = remoteEp.address().to_v6();
auto ipBin = addressClass.to_bytes();
memcpy(&binSourcePair[0], &ipBin[0], 16);
memcpy(&binSourcePair[16], &portNum, 2);
}
这就是这些函数的调用方式
remoteEp = socketPtr->remote_endpoint();
if (remoteEp.address().is_v4())
CmdInterpreter::makeSourcePairV4(remoteEp, remoteEp.port(), sourcePair);
else
CmdInterpreter::makeSourcePairV6(remoteEp, remoteEp.port(), sourcePair);
这里的问题是访问 IPv6 底层数据的唯一方法是使用 to_byte() ,它将以网络字节顺序提供数据。另外,我正在做一个无符号短的内存复制,它的长度是多字节的。这行得通吗?这是一种安全的方式吗?他们有什么解决方法吗?
【问题讨论】:
-
唯一想到的问题是端口号是本机字节顺序的,并且您没有显示可能位于 IPv4 二进制缓冲区末尾的垃圾。
-
@ZuodianHu 感谢评论,有人说“memcpy() 不修改字节顺序”。如果这是真的,我只关心网络字节顺序中的 IPv6。 SourcePair 仅在 IPv4 的情况下使用 [0-5](它是硬编码的)。
标签: c++ boost network-programming boost-asio asyncsocket