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

易逝的信仰 533

{{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应用迁移感兴趣的读者有所帮助。

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

打赏
暂无人打赏

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

本版版主

461
244
13

发帖

粉丝

关注

本版达人

feeling

本周分享达人

新手29676...

本周提问达人