【发布时间】:2012-07-12 07:04:57
【问题描述】:
我正在将 IPv4 应用程序移植到 AF 独立 代码库(它应该与 IPv4 和 IPv6 一起使用)。现在我尽可能地使用 sockaddr_storage,但是现在我必须设置(填充)一个 sockaddr_storage。但我不知道正确的方法是什么。之前的代码是:
// defined in data_socket.h
struct sockaddr_in laddr;
现在有这个函数可以设置sin_addr和sin_port:
void DataSocket::SetLocalAddr(const char *addr, const int port)
{
this->laddr.sin_port = htons(port);
if(addr != NULL)
this->laddr.sin_addr.s_addr = inet_addr(addr);
else
this->laddr.sin_addr.s_addr = inet_addr("0.0.0.0");
}
如您所见,这是旧样式(使用 IPv4)。
现在我的更改如下。首先,我将 sockaddr_in 更改为 sockaddr_storage
// defined in data_socket.h
struct sockaddr_storage laddr;
然后我把上面的代码改成支持IPv4和IPv6:
void DataSocket::SetLocalAddr(const char *addr, const int port)
{
switch (this->GetAddrFamily(addr)) {
case AF_INET:
(struct sockaddr_in *) this->laddr.sin_port = htons(port);
if(addr != NULL)
inet_pton(AF_INET, addr, (struct sockaddr_in *) this->laddr.sin_addr);
else
inet_pton(AF_INET, "0.0.0.0", (struct sockaddr_in *) this->laddr.sin_addr);
break;
case AF_INET6:
(struct sockaddr_in6 *) this->laddr.sin6_port = htons(port);
if(addr != NULL)
inet_pton(AF_INET6, addr, (struct sockaddr_in6 *) this->laddr.sin6_addr);
else
inet_pton(AF_INET6, "0:0:0:0:0:0:0:0", (struct sockaddr_in6 *) this->laddr.sin6_addr);
break;
default:
return NULL;
}
}
GetAddrFamily() 在哪里:
int DataSocket::GetAddrFamily(const char *addr)
{
struct addrinfo hints, *res;
int status, result;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(addr, 0, &hints, &res)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return false;
}
result = res->ai_family; // This might be AF_INET, AF_INET6,etc..
freeaddrinfo(res); // We're done with res, free it up
return result;
}
看来我的方法很复杂。这是正确的方法吗?因为我已经把 sockaddr_in 改成了 sockaddr_storage,其实我只是想要这个问题的反面:Getting IPV4 address from a sockaddr structure
我正在尝试找到最佳解决方案,例如这里:http://www.kame.net/newsletter/19980604/ 它说永远不要使用inet_ntop() 和inet_pton(),但是其他一些(如Beej 的网络教程)说inet_ntop() 和@987654334 @ 应该用于基于 IPv6 的应用程序。
我的实现方式正确还是应该改变它?
【问题讨论】:
-
这是我喜欢
boost::asio::ip::address的原因之一,它抽象了boost::asio::ip::address_v4和boost::asio::ip::address_v6。 -
当 C 获得成员函数时告诉我。
-
@DeadMG 抱歉
c标签
标签: c++ sockets ip-address ipv6