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 に変更したため、実際には、この質問の逆をしたいだけです: sockaddr 構造から IPV4 アドレスを取得する
たとえば、ここで最善の解決策を見つけようとしています: http://www.kame.net/newsletter/19980604/それは決して使用inet_ntop()
しないと言っていますinet_pton()
が、他のいくつか(Beejのネットワークチュートリアルなど)はそれを言ってinet_ntop()
おり、inet_pton()
使用する必要がありますIPv6ベースのアプリケーション向け。
私の実装方法は正しいですか、それとも変更する必要がありますか?