本文介绍了将C ++ TCP / IP应用程序从IPv4转换为IPv6。难?值得麻烦?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

多年来,我使用WinSock(路由器,Web /邮件/ FTP服务器等等...)为Windows开发了一小部分C ++服务器/客户端应用程序。

Over the years I've developed a small mass of C++ server/client applications for Windows using WinSock (Routers, Web/Mail/FTP Servers, etc... etc...).

我开始考虑越来越多地创建这些应用程序的IPv6版本(当然也保留原来的IPv4版本)。

I’m starting to think more and more of creating an IPv6 version of these applications (While maintaining the original IPv4 version as well, of course).

问题:


  1. 我可能遇到什么陷阱?

  2. 移植/转换是否困难?

  3. 转换是否值得?



对于参考(或乐趣),您可以查看和是您的朋友..尽可能地,我建议他们是您在寻求在现有应用程序中提供IPv4和IPv6支持的最好的朋友。

getaddrinfo and getnameinfo are your friends.. As much as possible I suggest they be your best friends in your quest to provide IPv4 and IPv6 support in an existing application.

如果通过添加IPv6支持完成,您最终还是将系统抽象为

If done right by adding IPv6 support you also end up abstracting the system to the point where an unknown future IP protocol can run without code modification.

通常在连接时,您将填写一个套接字结构,端口,地址族,IP地址,转换地址/端口到网络字节顺序等。

Normally when connecting you would fill out a socket structure, port, address family, IP address, converting address/ports to network byte order, etc.

使用 getaddrinfo ,您可以发送IP地址或主机名以及端口或端口名称,并返回一个具有结构和一切可以直接传递到 socket() connect()

With getaddrinfo you send an IP address or hostname and port or port name, and it returns a linked list with the structures and everything ready to be passed directly into socket() and connect().

getaddrinfo 对于使用两种IP协议至关重要,因为它知道主机是否具有IPv6或IPv4连接并且通过查看DNS AAAA vs A 记录并动态计算出哪个协议s)可用于为特定连接请求提供服务。

getaddrinfo is critical for working with both IP protocols as it knows if the host has IPv6 or IPv4 connectivity and it knows if the peer does as well by looking at DNS AAAA vs A records and dynamically figures out which protocol(s) are available to service the specific connection request.

我强烈建议不要使用 inet_pton() inet_addr c $ c>或具有IP版本的特定设备。在Windows平台上, inet_pton()与早期版本的MS Windows(XP,2003等)不兼容,除非你自己。还建议针对IPv4和IPv6的单独版本...这是不可行的技术解决方案,因为在不久的将来,两个协议将需要同时使用,人们可能不知道提前使用。套接字接口是抽象的,通过尝试创建IPv6套接字或尝试为侦听器设置IPv6双栈套接字选项,可以轻松检测双堆栈或IPv6支持。没有理由导致应用程序无法在不支持或不了解IPv6的系统上运行。

I highly advise against use of inet_pton(), inet_addr() or smiliar devices that are IP version specific. On the Windows platform specifically inet_pton() is not compatible with earlier versions of MS Windows (XP, 2003 et al.) unless you roll your own. Also advise against separate versions for IPv4 and IPv6... This is unworkable as a technical solution because in the near future both protocols will need to be used concurrently and people may not know ahead of time which to use. The socket interfaces are abstract and it's easy to detect dualstack or IPv6 support by attempting to create an IPv6 socket or attempt to set the IPv6 dualstack socket option for listeners. There is no reason the resulting application won't run on a system that does not support or know about IPv6.

对于传出的连接,使用 PF_UNSPEC getaddrinfo 中,以便在发出连接时为您选择地址系列。这个IMHO比双堆栈方法更好,因为它允许不支持dualstack的平台工作。

For outgoing connections use PF_UNSPEC in getaddrinfo so that the address family is chosen for you when making outgoing connections. This, IMHO, is better than the dualstack approach because it allows platforms that do not support dualstack to work.

对于传入连接,您可以单独绑定IPv4 / IPv6套接字它是合理的给定的设计或使用dualstack如果你不能做单独的侦听器。当使用dualstack getnameinfo 返回IPv4地址的一个IPv6地址,IMHO最终是非常无用的。一个小的实用程序可以将字符串转换为一个正常的IPv4地址。

For incoming connections you can either bind IPv4/IPv6 sockets separately if it's reasonable given the design or use dualstack if you can't do separate listeners. When using dualstack getnameinfo returns an IPv6 address for IPv4 addresses which IMHO ends up being quite useless. A small utility routine can convert the string to a normal IPv4 address.

根据我的经验,你完成了删除依赖关系的特定IP版本,管理代码比你开始。

From my experience when done right you've removed dependencies on specific IP versions and ended up with less socket management code than you started.

这篇关于将C ++ TCP / IP应用程序从IPv4转换为IPv6。难?值得麻烦?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 07:27