Ein*_*ein 19
getaddrinfo和getnameinfo是你的朋友..我建议他们尽可能地成为你在现有应用程序中提供IPv4和IPv6支持的最好朋友.
如果通过添加IPv6支持来完成,您最终也会将系统抽象到未知未来IP协议无需代码修改即可运行的程度.
通常在连接时,您将填写套接字结构,端口,地址系列,IP地址,将地址/端口转换为网络字节顺序等.
随着getaddrinfo您发送IP地址或主机名和端口或端口名称,它返回一个链接列表与结构和一切准备直接传递到socket()和connect().
getaddrinfo对于使用两种IP协议至关重要,因为它知道主机是否具有IPv6或IPv4连接,并且通过查看DNS AAAA与A记录并且动态地确定哪些协议可用于为特定连接提供服务,它知道对等方是否也这样做请求.
我强烈建议不要使用inet_pton(),inet_addr()或者是IP版本特定smiliar设备.在Windows平台上,特别inet_pton()是与早期版本的MS Windows(XP,2003等人)不兼容,除非您自己推出.同时建议不要使用IPv4和IPv6的单独版本......作为一种技术解决方案,这是不可行的,因为在不久的将来,两种协议都需要同时使用,人们可能不知道提前使用哪种协议.套接字接口是抽象的,通过尝试创建IPv6套接字或尝试为侦听器设置IPv6双栈套接字选项,可以轻松检测双栈或IPv6支持.没有理由生成的应用程序不会在不支持或不了解IPv6的系统上运行.
对于传出连接,请使用PF_UNSPECin,getaddrinfo以便在进行传出连接时为您选择地址系列.恕我直言,这比双栈方法更好,因为它允许不支持双栈的平台工作.
对于传入连接,如果给定设计是合理的,则可以单独绑定IPv4/IPv6套接字,如果不能执行单独的侦听器,则可以使用dualstack.当使用dualstack getnameinfo返回IPv4地址的IPv6地址时,IMHO最终会变得毫无用处.一个小的实用程序例程可以将字符串转换为普通的IPv4地址.
从我的经验来看,你已经删除了对特定IP版本的依赖性,最终得到的套接字管理代码比你开始时少.
Jer*_*ner 12
我大约一年前在我以前的IPv4 网络库中添加了IPv6支持,我没有发现它非常困难或创伤.
唯一的区别在于如何存储IP地址:
在IPv4中,你将它们存储为sockaddr_ins(或者如果你像我一样顽皮,就像uint32_t那样).
对于IPv6,您需要将它们存储为sockaddr_in6(或等效的128位结构).
一个好的转换前步骤是遍历您的代码并查找当前存储IPv4地址的所有位置,并将它们抽象为通用IP地址类,以后可以在内部重新实现为IPv4地址或IPv6地址.
然后重新测试,以确保没有被打破了IPv4的模式......一旦这样签出,你应该能够使切换到IPv6的只有几个变化(主要是改变PF_INET到PF_INET6,inet_aton()要inet_pton()等...).
默认情况下,我的库仍然仅作为IPv4发布,但可以选择定义预处理器宏(-DMUSCLE_USE_IPV6)以在IPv6感知模式下重新编译它.
这样,它仍然可以在不支持IPv6的系统上编译.我在此过程中发现的一个非常有用的功能是IPv4映射的IPv6地址:通过指定其中一个(本质上是一个0xFFFF前缀的IPv4地址),您将得到一个可以同时与IPv4和IPv6通信的套接字,从而可以使用一个服务器即可跟IPv4和IPv6客户端同时,无需编写单独的IPv4和IPv6的代码路径的一切.
至于是否值得努力,这实际上取决于你打算用代码做什么.我认为这是一个很好的教育经验,如果没有别的,它确实允许你的软件在IPv6环境中使用,随着时间的推移,这将变得更加普遍.
glibc的维护者Ulrich Drepper有一篇关于这个主题的好文章,
http://people.redhat.com/drepper/userapi-ipv6.html
但是不要忘记Richard Steven的书,Unix网络编程,第1卷:套接字网络API,以获得良好的实践.
| 归档时间: |
|
| 查看次数: |
12430 次 |
| 最近记录: |