【每日一记12】+第11天:IP双栈环境下网络应用迁移(七)
  

易逝的信仰 518

{{ttag.title}}
11.    IPv6客户端程序设计

IPv6客户端通过指定地址或域名来访问IPv4以及IPv6的服务端,如果服务提供方是IPv4,那么需要用IPv4-mapped IPv6地址的形式去访问。针对域名访问,需要采用DNS实现名称来解析,在IPv4环境下的解析库函数调用有两个:gethostbyname(正向解析)、gethostbyaddr(反向解析),此类解析用于IPv4环境。IPv6环境下则采用getaddrinfo和getnameinfo来解析IPv4和IPv6地址信息,getaddrinfo根据域名/服务名称以及相关hints等信息返回一组A和AAAA记录,每条返回的记录附加有用于创建socket所需的AF_xxx以及SOCK_xxx等信息,客户端程序通常利用循环语句针对getaddrinfo返回地址列表的每一项尝试创建socket以及connect对端,直到发现针对一条地址记录的socket和connect调用都返回成功为止。

客户端只需要知道服务端的域名以及服务端口,采用getaddrinfo调用返回的地址列表信息,就可以创建合适的地址族的socket和服务端连接。

n  Python的getaddrinfo使用示例

解析www.hpe.com的地址信息,返回一个包含IPv4以及IPv6地址的列表

#python

>>> from socket import *

>>>from os import *

>>> from pprint import pprint

>>> list=getaddrinfo("www.hpe.com","www")

>>> pprint(list)

[(2, 1, 6, '', ('23.7.213.221', 80)),

(2, 2, 17, '', ('23.7.213.221', 80)),

(10, 1, 6, '', ('2600:1417:a000:195::1463', 80, 0, 0)),

(10, 2, 17, '', ('2600:1417:a000:195::1463', 80, 0, 0)),

(10, 1, 6, '', ('2600:1417:a000:1b4::1463', 80, 0, 0)),

>>> list[0][0:3]

(2, 1, 6)

>>> list[0][4]

('23.7.213.221', 80)

连接DNS解析返回列表中的第一项的IPv4地址,成功后在系统层面输出TCP连接的四元组信息:

>>> s=socket(*list[0][0:3])

>>> s.connect(list[0][4])

>>> system("ss -tn|grep 80")

ESTAB      0      0      192.168.100.165:39838      23.7.213.221:80    0

尝试用DNS解析返回列表中的第三项IPv6的地址信息来连接www.hpe.com,由于测试系统centos无法通达服务端IPv6地址,连接失败:

>>> s1=socket(*list[2][0:3])

>>> s1.connect(list[2][4])

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "/usr/lib64/python2.7/socket.py", line 224, in meth

    return getattr(self._sock,name)(*args)

socket.error: [Errno 101] Network is unreachable

>>>

n  C语言的getaddrinfo使用示例:

main(int argc, char **argv)

{

         struct addrinfo         *res, *ainfo;

         struct addrinfo        hints;

         int   error;

         struct sockaddr_in6        peeraddr6;

         struct sockaddr_in6         addr6;

         char connect_addr[INET6_ADDRSTRLEN];

         if (argc != 2) {

                   fprintf(stderr, "Usage:  %s <remote host>\n", argv[0]);

                   exit(1);

         }

         memset ((char *)&hints, 0, sizeof(hints));

         hints.ai_socktype = SOCK_STREAM;

         error =  getaddrinfo(argv[1], "www", &hints, &res);

         if (error != 0)

                   exit(1);

         for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) {

s = socket (ainfo->ai_family,ainfo->ai_socktype,ainfo->ai_protocol);

                   if (s == -1)

         continue;

                   if (connect(s, ainfo->ai_addr, ainfo->ai_addrlen) == -1)

                            continue;

                   else

                            break;

         }

………………………..

}

java,Python等语言对这些细节都做了很好的封装,如python中的socket.create_connection()就可以实现以上C代码的所有功能。

12.  结束语

本文对基于不同IP地址族的应用的访问方式以及具体实现的方法进行了简要说明, 同时也介绍了如何改造现有IPv4应用以适应新的IPv6环境,介绍了同时适用于IPv4以及IPv6环境的应用的方法。IPv6应用迁移是未来应用迁移发展的方向,希望本文内容对IPv6应用迁移感兴趣的读者有所帮助。

打赏鼓励作者,期待更多好文!

打赏
暂无人打赏

伊利丹·怒风 发表于 2021-6-11 09:41
  
谢谢分享,有助于工作!
伊利丹·怒风 发表于 2021-7-14 14:00
  
感谢分享,有助于工作,学习学习
发表新帖
热门标签
全部标签>
每日一问
技术盲盒
技术笔记
干货满满
技术咨询
功能体验
产品连连看
新版本体验
GIF动图学习
自助服务平台操作指引
标准化排查
运维工具
2023技术争霸赛专题
通用技术
秒懂零信任
技术晨报
信服课堂视频
用户认证
安装部署配置
安全攻防
SDP百科
设备维护
深信服技术支持平台
社区帮助指南
答题自测
每日一记
玩转零信任
畅聊IT
专家问答
技术圆桌
在线直播
MVP
网络基础知识
升级
上网策略
测试报告
日志审计
问题分析处理
流量管理
云计算知识
原创分享
解决方案
sangfor周刊
VPN 对接
项目案例
SANGFOR资讯
专家分享
技术顾问
信服故事
功能咨询
终端接入
授权
资源访问
地址转换
虚拟机
存储
迁移
加速技术
排障笔记本
产品预警公告
信服圈儿
S豆商城资讯
技术争霸赛
「智能机器人」
追光者计划
答题榜单公布
纪元平台
卧龙计划
华北区拉练
天逸直播
以战代练
山东区技术晨报
文档捉虫活动
齐鲁TV
华北区交付直播
每周精选

本版版主

461
244
13

发帖

粉丝

关注

本版达人

feeling

本周分享达人

新手29676...

本周提问达人