实现套接字接口以支持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
请建议是否有更好的方法或第二个过程中的缺陷。
答案 0 :(得分:5)
从技术上讲,无论选项(1)还是(2),都应迁移到与IP系列无关的API,并使用struct sockaddr
和struct 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.html和http://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
适合sockaddr
,sockaddr_in6
却不适合!但是,sockaddr_storage
足以处理IPv4和IPv6。
转而使用:
struct sockaddr_storage salocal;
struct sockaddr_in6 * s_in6 = (struct sockaddr_in6 *) &salocal;
然后,在调用bind之类的方法时,强制转换为(struct sockaddr *)
。