如果单纯的从代码角度来看,IPV4和IPV6的变化基本不大,主要是围绕着sockaddr系列结构体的变化,API层面基本没变化,变化最大的就是将字符串解析成地址结构体的那几个函数,为了解析字符串中的IPV4地址,IPV4使用 inet_addr()函数,在升级之后,更改为inet_pton函数,这个函数除了地址字符串,还需要指定IP协议版本,另外,对域名的解析也有变化,IPV4使用gethostbyname()函数,而新的协议采用getaddrinfo()函数,只要处理好了这几个函数,IPV4 V6混合编码就基本OK了。
IPV4 IPV6混合编码最重要的就是理清sockaddr系列结构体的关系,主要有这几个结构体:
sockaddr // 最基本的结构体,所有的API都是用这个结构体指针,用结构体长度来判断使用哪个结构体;
sockaddr_in // IPV4使用的地址结构;
sockaddr_in6 // IPV6使用的地址结构;
sockaddr_storage // 通用的地址存储结构体,建议尽可能的用这个结构体来编码;
这儿给出一个解析地址的函数实现:
bool CSocketUtility::DomainAnalyze(tagDomain & domain)
{
bool result = false;
if( !domain.host.empty() && domain.data.GetCapacity() )
{
if( IsIPV4Address( domain.host.c_str() ) )
{
if( domain.data.GetCapacity() >= sizeof(sockaddr_in) &&
inet_pton( AF_INET, domain.host.c_str(), & (
domain.data.Query<sockaddr_in>() -> sin_addr ) ) > 0 )
{
// return 1, succeed.
domain.data.SetLength( sizeof(sockaddr_in) );
domain.data.Query<sockaddr_in>() -> sin_family = AF_INET;
domain.data.Query<sockaddr_in>() -> sin_port = htons( domain.port );
result = true;
}
}
else
if( IsIPV6Address( domain.host.c_str() ) )
{
if( domain.data.GetCapacity() >= sizeof(sockaddr_in6) &&
inet_pton( AF_INET6, domain.host.c_str(), & (
domain.data.Query<sockaddr_in6>() -> sin6_addr ) ) > 0 )
{
// return 1, succeed.
domain.data.SetLength( sizeof(sockaddr_in6) );
domain.data.Query<sockaddr_in6>() -> sin6_family = AF_INET6;
domain.data.Query<sockaddr_in6>() -> sin6_port = htons( domain.port );
&nbs

本文详细介绍了IPv4和IPv6在网络编程中的混合编码技巧,重点解析了sockaddr系列结构体的变化,以及如何使用inet_pton和getaddrinfo函数进行地址解析,通过实例展示了监听和连接操作的兼容性修改。
最低0.47元/天 解锁文章
4543

被折叠的 条评论
为什么被折叠?



