Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 实现套接字接口以同时支持IPV6和IPV4的最佳方法_C++_Sockets_Ipv6 - Fatal编程技术网

C++ 实现套接字接口以同时支持IPV6和IPV4的最佳方法

C++ 实现套接字接口以同时支持IPV6和IPV4的最佳方法,c++,sockets,ipv6,C++,Sockets,Ipv6,实现套接字接口以支持IPV6的最佳方式是什么。 现有代码仅支持IPV4。现在,为了支持IPV6,我也没有什么疑问 1) 我应该用IPV6 API替换IPV4的所有API吗。比如AF_INET by AF_INET6,sockaddr_in by sockaddr_in6等等。这些新API是否支持这两种协议 2) 或者我应该保持这种状态 #ifdef IPV6_SUPPORT sockaddr_in6 addr; RTMemoryUtil::memset( &addr, 0

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

1) 我应该用IPV6 API替换IPV4的所有API吗。比如AF_INET by AF_INET6,sockaddr_in by sockaddr_in6等等。这些新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

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

使用Boost.Asio之类的现代网络编程库,或者(如果您想使用C/sockets方法)接口。后者是大约十年前设计的,因此它应该在任何地方都可以使用(至少是Windows、Linux、BSD、Mac OS X)。它还有一个额外的魅力,即它还可以支持异国情调的网络协议,并提供适当的OS/C库支持,因此您可以声称支持协议无关的分布式云计算®。

使用Boost.Asio等现代网络编程库,或者(如果您想使用C/sockets方式)接口。后者是大约十年前设计的,因此它应该在任何地方都可以使用(至少是Windows、Linux、BSD、Mac OS X)。它还有一个额外的魅力,即它还可以支持异域网络协议,提供适当的OS/C库支持,因此您可以声称支持协议独立的分布式云计算®。

根据目标平台,您可以设置套接字选项,以便在实现适当的双堆栈的情况下,使套接字能够同时处理IPv4和IPv6。这将使你的大部分工作付诸东流

并且可能有助于开始


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

根据目标平台,如果实现了合适的双堆栈,您可以设置套接字选项以使套接字能够同时处理IPv4和IPv6。这将使你的大部分工作付诸东流

并且可能有助于开始


对于许多用途,它可能与现有的IPv4代码没有多大变化。

从技术上讲,无论是选项(1)还是(2),您都应该迁移到IP系列不可知API,并使用
struct sockaddr
struct sockaddr\u存储
,而不是IPv4和IPv6硬连线结构。Stevens给出了创建不可知API的好例子,下面是我采用的类似方法:


从技术上讲,无论是选项(1)还是(2),您都应该迁移到与IP系列无关的API,并使用
struct sockaddr
struct sockaddr\u存储
,而不是IPv4和IPv6硬连线结构。Stevens给出了创建不可知API的好例子,下面是我采用的类似方法:


其他答案是正确的,但还有另一件必须考虑的事情: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\u in
适合
sockaddr
,而
sockaddr\u in 6
不适合!但是,
sockaddr\u存储
足够大,可以同时处理IPv4和IPv6

相反,切换到类似以下内容:

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

然后,当调用bind、cast to
(struct sockaddr*)

等方法时,其他答案都是正确的,但需要考虑的另一个基本问题是:sockaddr结构小于IPv6要求的sockaddr\u in6结构。我正在移植具有以下内容的代码:

struct sockaddr salocal;
struct sockaddr_in * s_in = (struct sockaddr_in *) &salocal;
将第二行替换为:

struct sockaddr_in6 * s_in6 = (struct sockaddr_in6 *) &salocal;
导致问题的原因是,
sockaddr\u in
适合
sockaddr
,而
sockaddr\u in 6
不适合!但是,
sockaddr\u存储
足够大,可以同时处理IPv4和IPv6

相反,切换到类似以下内容:

struct sockaddr_storage salocal;
struct sockaddr_in6 * s_in6 = (struct sockaddr_in6 *) &salocal;
然后,当调用像bind这样的方法时,cast to
(struct sockaddr*)

“或者”将不起作用。“两者都”是目前的做法,“要么/要么”行不通。“两者”是目前的做法。