IPv6 Winsock アプリケーションのデータ構造の変更
IPv6 のサポートを追加する場合は、アプリケーションで適切なサイズのデータ構造が定義されていることを確認する必要があります。 IPv6 アドレスのサイズは、IPv4 アドレスよりもはるかに大きくなります。 IP アドレスを格納するときに IPv4 アドレスのサイズを処理するようにハードコーディングされた構造体は、アプリケーションで問題を引き起こすので、変更する必要があります。
推奨事項
構造のサイズを適切に設定するための最善の方法は、 SOCKADDR_STORAGE 構造を使用することです。 SOCKADDR_STORAGE構造は、IP アドレス バージョンに依存しません。 IP アドレスを格納するために SOCKADDR_STORAGE 構造を使用すると、IPv4 アドレスと IPv6 アドレスを 1 つのコード ベースで適切に処理できます。
次の例は、付録 B にある Server.c ファイルからの抜粋であり、 SOCKADDR_STORAGE 構造の適切な使用を識別します。 この例で示すように、構造が適切に使用されると、IPv4 または IPv6 アドレスが正常に処理されます。
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
#define BUFFER_SIZE 512
#define DEFAULT_PORT "27015"
int main(int argc, char **argv)
{
char Buffer[BUFFER_SIZE] = {0};
char *Hostname;
int Family = AF_UNSPEC;
int SocketType = SOCK_STREAM;
char *Port = DEFAULT_PORT;
char *Address = NULL;
int i = 0;
DWORD dwRetval = 0;
int iResult = 0;
int FromLen = 0;
int AmountRead = 0;
SOCKADDR_STORAGE From;
WSADATA wsaData;
ADDRINFO *AddrInfo = NULL;
ADDRINFO *AI = NULL;
// Parse arguments
if (argc >= 1) {
Hostname = argv[1];
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
From.ss_family = (ADDRESS_FAMILY) Family;
//...
return 0;
}
Note
SOCKADDR_STORAGE構造は、Windows XP の新しい構造です。
回避するコード
通常、多くのアプリケーションでは、プロトコルに依存しないアドレスを格納するために sockaddr 構造体を使用するか、IP アドレスの sockaddr_in 構造を使用しました。 sockaddr 構造体も sockaddr_in 構造も IPv6 アドレスを保持するのに十分な大きさがないため、アプリケーションが IPv6 互換である場合は両方とも不十分です。
コーディング タスク
既存のコード ベースを IPv4 から IPv4 と IPv6 の相互運用性に変更するには
- Checkv4.exe ユーティリティを取得します。 このユーティリティは、MSDN サブスクリプションを通じて、または Web からダウンロードとして利用できる Microsoft Windows ソフトウェア開発キット (SDK) に含まれています。
- コードに対して Checkv4.exe ユーティリティを実行します。 Checkv4.exe ユーティリティの使用に関するセクションで、ファイルに対して Checkv4.exe ユーティリティを実行する方法について説明します。
- ユーティリティは 、sockaddr または sockaddr_in 構造体の使用を警告し、IPv6 互換構造体 SOCKADDR_STORAGEに置き換える方法に関する推奨事項を提供します。
- SOCKADDR_STORAGE 構造体を 使用するには、このようなインスタンスと関連するコードを適宜置き換えます。
または、コード ベースで sockaddr および sockaddr_in 構造体のインスタンスを検索し、そのようなすべての使用法 (および必要に応じて他の関連するコード) を SOCKADDR_STORAGE 構造体に変更できます。
Note
addrinfo と SOCKADDR_STORAGE 構造体には、それぞれプロトコルとアドレス ファミリ メンバー (ai_familyとss_family) が含まれます。 RFC 2553 は addrinfo のai_family メンバーを int として指定しますが、ss_familyは short として指定されます。そのため、これらのメンバー間の直接コピーはコンパイラ エラーになります。
関連トピック
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示