【发布时间】:2013-05-21 16:56:37
【问题描述】:
这是Connecting IPv4 client to IPv6 server: connection refused 的延续。我正在尝试使用双栈套接字,并试图了解带有 IPV6_V6ONLY 的 setsockopt 的用途。在链接的问题上,我被告知“如果您还将服务器绑定到 IPv6 映射的 IPv4 地址,将 IPV6_V6ONLY 设置为 0 会很有用”。我在下面完成了这项工作,并希望我的服务器能够接受来自 IPv6 和 IPv4 客户端的连接。但令人震惊的是,当我使用 V4 和 V6 套接字运行客户端时,两者都无法连接!
有人可以告诉我我做错了什么,还是我完全误解了 IPv6 双栈功能?
服务器:
void ConvertToV4MappedAddressIfNeeded(PSOCKADDR pAddr)
{
// if v4 address, convert to v4 mapped v6 address
if (AF_INET == pAddr->sa_family)
{
IN_ADDR In4addr;
SCOPE_ID scope = INETADDR_SCOPE_ID(pAddr);
USHORT port = INETADDR_PORT(pAddr);
In4addr = *(IN_ADDR*)INETADDR_ADDRESS(pAddr);
ZeroMemory(pAddr, sizeof(SOCKADDR_STORAGE));
IN6ADDR_SETV4MAPPED(
(PSOCKADDR_IN6)pAddr,
&In4addr,
scope,
port
);
}
}
addrinfo* result, hints;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
int nRet = getaddrinfo("powerhouse", "82", &hints, &result);
SOCKET sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
int no = 0;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&no, sizeof(no)) != 0)
return -1;
ConvertToV4MappedAddressIfNeeded(result->ai_addr);
if (bind(sock, result->ai_addr, 28/*result->ai_addrlen*/) == SOCKET_ERROR)
return -1;
if (listen(sock, SOMAXCONN) == SOCKET_ERROR)
return -1;
SOCKET sockClient = accept(sock, NULL, NULL);
printf("Got one!\n");
客户:
addrinfo* result, *pCurrent, hints;
char szIPAddress[INET6_ADDRSTRLEN];
memset(&hints, 0, sizeof hints); // Must do this!
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
const char* pszPort = "82";
if (getaddrinfo("powerhouse", "82", &hints, &result) != 0)
return -1;
SOCKET sock = socket(AF_INET, result->ai_socktype, result->ai_protocol);
int nRet = connect(sock, result->ai_addr, result->ai_addrlen);
【问题讨论】:
-
您是否尝试过将
hints.ai_family = AF_INET;设置为hints.ai_family = AF_INET6;时会发生什么?正如我现在所看到的,您正在查找的是IPv4 通配符地址,而不是IPv6 -
不确定你的意思;当我传递我的机器名称(“powerhouse”)时,我没有查找通配符地址......除非我误解了你??
-
啊,我不记得节点名称覆盖了 AI_PASSIVE 标志。 AI_PASSIVE 被忽略,因此您应该删除它以使代码更清晰。 powerhouse 解析到什么(如果您键入 host powerhouse)?
-
我在 Windows 上,所以 'host' 不起作用 :) 不过,好消息是,我关闭了防火墙,现在上面的 IPv4 客户端代码连接正常;当它是 IPv6 时,虽然它仍然无法连接。我现在只需要从下面的 Sander 的 cmets 中了解整个 IPv6 内容...