实现套接字接口以支持IPV6和IPV4的最佳方式

时间:2011-05-04 23:04:19

标签: c++ sockets ipv6

实现套接字接口以支持IPV6的最佳方法是什么。 现有代码仅支持IPV4。现在,为了支持IPV6,我也很少有疑问......

1)_I应该用IPV6 API替换IPV4的所有API。通过AF_INET6说AF_INET,通过sockaddr_in6说sockaddr_in等。这些新API是否支持这两种协议。

2)或者我应该这样保持这种状态......

#ifdef IPV6_SUPPORT
    sockaddr_in6 addr;
    RTMemoryUtil::memset( &addr, 0, (int)sizeof( addr ) );
    addr.sin6_family = AF_INET6;
    addr.sin6_port   = (unsigned short)htons( port );
    RTMemoryUtil::memcpy( &addr.sin6_addr, address, (int)sizeof( *address ) );
#else
    sockaddr_in  addr;
    RTMemoryUtil::memset( &addr, 0, (int)sizeof( addr ) );
    addr.sin_family = AF_INET;
    addr.sin_port   = (unsigned short)htons( port );
    RTMemoryUtil::memcpy( &addr.sin_addr, address, (int)sizeof( *address ) );
#endif

请建议是否有更好的方法或第二个过程中的缺陷。

4 个答案:

答案 0 :(得分:5)

从技术上讲,无论选项(1)还是(2),都应迁移到与IP系列无关的API,并使用struct sockaddrstruct sockaddr_storage代替IPv4和IPv6硬连线结构。史蒂文斯提供了创建不可知API的好例子,这是我采用的类似方法:

http://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/sockaddr.c

答案 1 :(得分:4)

要么使用现代网络编程库,例如Boost.Asio,要么(如果你想用C /套接字方式)getaddrinfo接口。后者是在大约十年前设计的,所以它几乎可以在任何地方使用(至少Windows,Linux,BSD,Mac OS X)。它具有额外的魅力,它还可以支持异国情调的网络协议,并提供适当的OS / C库支持,因此您可以声称支持与协议无关的分布式云计算®。

答案 2 :(得分:3)

根据目标平台,您可以设置套接字选项,以便在实现合适的双栈时使套接字能够同时处理IPv4和IPv6。它将代表您删除大部分工作。

http://long.ccaba.upc.es/long/045Guidelines/eva/ipv6.htmlhttp://msdn.microsoft.com/en-us/library/bb513665(v=vs.85).aspx可能会有所帮助。

对于许多用途,它可能与您现有的IPv4代码没有太大关系。

答案 3 :(得分:0)

其他答案是针对目标的,但还有另一个需要考虑的重要事项:sockaddr结构比IPv6所需的sockaddr_in6结构更小。我正在移植具有此代码的代码:

struct sockaddr salocal;
struct sockaddr_in * s_in = (struct sockaddr_in *) &salocal;

用第二行替换第二行:

struct sockaddr_in6 * s_in6 = (struct sockaddr_in6 *) &salocal;

导致问题,因为虽然sockaddr_in适合sockaddrsockaddr_in6却不适合!但是,sockaddr_storage足以处理IPv4和IPv6。

转而使用:

struct sockaddr_storage salocal;
struct sockaddr_in6 * s_in6 = (struct sockaddr_in6 *) &salocal;

然后,在调用bind之类的方法时,强制转换为(struct sockaddr *)