ADDRINFOA
構造体サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。
フィールド
| フィールド | 型 | サイズ | x64 | x86 | 説明 | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ai_flags | INT | 4 | +0 | +0 | getaddrinfo 関数で使用されるオプションを示すフラグです。 ai_flags メンバーでサポートされる値は、Windows 7 以降の Windows SDK では Ws2def.h ヘッダーファイルで定義されています。Windows Server 2008 および Windows Vista の Windows SDK では、これらの値は Ws2tcpip.h ヘッダーファイルで定義されています。Windows Server 2003 および Windows XP の Platform SDK では、これらの値は Ws2tcpip.h ヘッダーファイルで定義されています。ai_flags メンバーでサポートされる値には、次のオプションを組み合わせて指定できます。
| ||||||||||||||||||||||||
| ai_family | INT | 4 | +4 | +4 | アドレスファミリです。アドレスファミリに指定できる値は Winsock2.h ヘッダーファイルで定義されています。 Windows Vista 以降向けにリリースされた Windows SDK ではヘッダーファイルの構成が変更されており、アドレスファミリに指定できる値は Ws2def.h ヘッダーファイルで定義されています。Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用しないでください。 現在サポートされている値は AF_INET または AF_INET6 で、これらはそれぞれ IPv4 と IPv6 のインターネットアドレスファミリの形式です。その他のアドレスファミリ (たとえば NetBIOS で使用する AF_NETBIOS) は、そのアドレスファミリ用の Windows ソケットサービスプロバイダーがインストールされている場合にサポートされます。なお、AF_ で始まるアドレスファミリ定数と PF_ で始まるプロトコルファミリ定数の値は同一である (たとえば AF_UNSPEC と PF_UNSPEC) ため、どちらの定数も使用できます。 次の表はアドレスファミリの代表的な値を示していますが、これ以外にも多くの値を指定できます。
| ||||||||||||||||||||||||
| ai_socktype | INT | 4 | +8 | +8 | ソケットの種類です。ソケットの種類に指定できる値は Winsock2.h ヘッダーファイルで定義されています。 次の表は、Windows Sockets 2 でサポートされるソケットの種類の値を示しています。
Windows Sockets 2 では、新しいソケットの種類が導入されました。アプリケーションは、 WSAEnumProtocols 関数を使用して、利用可能な各トランスポートプロトコルの属性を実行時に動的に取得できます。これにより、アプリケーションはアドレスファミリごとに指定可能なソケットの種類とプロトコルのオプションを判断し、その情報をこのパラメーターの指定に利用できます。Winsock2.h および Ws2def.h ヘッダーファイル内のソケットの種類の定義は、新しいソケットの種類、アドレスファミリ、プロトコルが定義されるたびに随時更新されます。 Windows Sockets 1.1 では、指定できるソケットの種類は SOCK_DATAGRAM と SOCK_STREAM のみです。 | ||||||||||||||||||||||||
| ai_protocol | INT | 4 | +12 | +12 | プロトコルの種類です。指定できるオプションは、指定したアドレスファミリとソケットの種類に依存します。ai_protocol に指定できる値は Winsock2.h および Wsrm.h ヘッダーファイルで定義されています。 Windows Vista 以降向けにリリースされた Windows SDK ではヘッダーファイルの構成が変更されており、このメンバーには Ws2def.h ヘッダーファイルで定義されている IPPROTO 列挙型の値のいずれかを指定できます。Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用しないでください。 ai_protocol に 0 を指定した場合、呼び出し元はプロトコルを指定しないことを意味し、使用する ai_protocol はサービスプロバイダーが選択します。IPv4 および IPv6 以外のプロトコルでは、ai_protocol に 0 を設定してください。 次の表は ai_protocol メンバーの代表的な値を示していますが、これ以外にも多くの値を指定できます。
ai_family メンバーが AF_IRDA の場合、ai_protocol は 0 でなければなりません。 | ||||||||||||||||||||||||
| ai_addrlen | UINT_PTR | 8/4 | +16 | +16 | ai_addr メンバーが指すバッファーの長さ (バイト単位) です。 | ||||||||||||||||||||||||
| ai_canonname | LPSTR | 8/4 | +24 | +20 | ホストの正規名です。 | ||||||||||||||||||||||||
| ai_addr | SOCKADDR* | 8/4 | +32 | +24 | sockaddr 構造体へのポインターです。返される各 addrinfo 構造体の ai_addr メンバーは、値が設定されたソケットアドレス構造体を指します。返される各 addrinfo 構造体におけるその長さ (バイト単位) は、ai_addrlen メンバーで示されます。 | ||||||||||||||||||||||||
| ai_next | ADDRINFOA* | 8/4 | +40 | +28 | リンクリスト内の次の構造体へのポインターです。リンクリストの最後の addrinfo 構造体では、このパラメーターは NULL に設定されます。 |
公式ドキュメント
addrinfo 構造体は、 getaddrinfo 関数がホストのアドレス情報を保持するために使用します。
解説(Remarks)
addrinfo 構造体は、ANSI 版の getaddrinfo 関数がホストのアドレス情報を保持するために使用します。
addrinfoW 構造体は、Unicode 版の GetAddrInfoW 関数で使用される、この構造体のバージョンです。
Ws2tcpip.h ヘッダーファイル内のマクロにより、ADDRINFOT 構造体と、大文字小文字混在の関数名 GetAddrInfo が定義されます。GetAddrInfo 関数は、nodename および servname パラメーターに TCHAR 型のポインターを、hints および res パラメーターに ADDRINFOT 型のポインターを指定して呼び出します。UNICODE または _UNICODE が定義されていない場合、ADDRINFOT は addrinfo 構造体として定義され、GetAddrInfo はこの関数の ANSI 版である getaddrinfo として定義されます。UNICODE または _UNICODE が定義されている場合、ADDRINFOT は addrinfoW 構造体として定義され、GetAddrInfo はこの関数の Unicode 版である GetAddrInfoW として定義されます。
getaddrinfo の呼び出しが成功すると、 addrinfo 構造体のリンクリストが、getaddrinfo 関数に渡した res パラメーターに返されます。このリストは、返された各 addrinfo 構造体の ai_next メンバーにあるポインターを NULL ポインターに達するまでたどることで処理できます。返される各 addrinfo 構造体の ai_family、ai_socktype、ai_protocol の各メンバーは、 socket 関数または WSASocket 関数の呼び出しにおける対応する引数に相当します。また、返される各 addrinfo 構造体の ai_addr メンバーは、値が設定されたソケットアドレス構造体を指し、その長さは同じ構造体の ai_addrlen メンバーで示されます。
旧バージョンの Windows における getaddrinfo と addrinfo 構造体のサポート
addrinfo 構造体を使用する getaddrinfo 関数は、Windows XP 以降の Ws2_32.dll に追加されました。addrinfo 構造体は、Windows XP 以降向けにリリースされた Platform SDK、および Windows Vista 以降向けにリリースされた Windows SDK に含まれる Ws2tcpip.h ヘッダーファイルで定義されています。getaddrinfo 関数と addrinfo 構造体を使用するアプリケーションをそれ以前のバージョンの Windows (Windows 2000) で実行するには、Ws2tcpip.h と Wspiapi.h をインクルードする必要があります。Wspiapi.h インクルードファイルを追加すると、getaddrinfo 関数は Wspiapi.h 内のインライン関数 WspiapiGetAddrInfo として定義されます。実行時には、Ws2_32.dll または Wship6.dll (Windows 2000 用 IPv6 Technology Preview で getaddrinfo を含むファイル) が getaddrinfo を提供していない場合に、Wspiapi.h ヘッダーファイル内のコードに基づく getaddrinfo の実装がインラインで使用されるように WspiapiGetAddrInfo 関数が実装されています。このインラインコードは、getaddrinfo 関数をネイティブにサポートしていない旧来の Windows プラットフォームで使用されます。
IPv6 プロトコルは、Windows 2000 用 IPv6 Technology Preview がインストールされている場合に Windows 2000 でサポートされます。それ以外の場合、Windows XP より前のバージョンの Windows における getaddrinfo のサポートは、IPv4 の名前解決の処理に限られます。
addrinfoW 構造体を使用する GetAddrInfoW 関数は、getaddrinfo 関数および対応する addrinfo 構造体の Unicode 版です。GetAddrInfoW 関数は、Windows XP Service Pack 2 (SP2) で Ws2_32.dll に追加されました。GetAddrInfoW 関数と addrinfoW 構造体は、Windows XP SP2 より前のバージョンの Windows では使用できません。
Examples
次のコード例は、addrinfo 構造体の使用方法を示しています。
#undef UNICODE
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
int __cdecl main(int argc, char **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
INT iRetval;
DWORD dwRetval;
int i = 1;
struct addrinfo *result = NULL;
struct addrinfo *ptr = NULL;
struct addrinfo hints;
struct sockaddr_in *sockaddr_ipv4;
// struct sockaddr_in6 *sockaddr_ipv6;
LPSOCKADDR sockaddr_ip;
char ipstringbuffer[46];
DWORD ipbufferlength = 46;
// Validate the parameters
if (argc != 3) {
printf("usage: %s <hostname> <servicename>\n", argv[0]);
printf(" provides protocol-independent translation\n");
printf(" from an ANSI host name to an IP address\n");
printf("%s example usage\n", argv[0]);
printf(" %s www.contoso.com 0\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
//--------------------------------
// Setup the hints address info structure
// which is passed to the getaddrinfo() function
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
printf("Calling getaddrinfo with following parameters:\n");
printf("\tnodename = %s\n", argv[1]);
printf("\tservname (or port) = %s\n\n", argv[2]);
//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
dwRetval = getaddrinfo(argv[1], argv[2], &hints, &result);
if ( dwRetval != 0 ) {
printf("getaddrinfo failed with error: %d\n", dwRetval);
WSACleanup();
return 1;
}
printf("getaddrinfo returned success\n");
// Retrieve each address and print out the hex bytes
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
printf("getaddrinfo response %d\n", i++);
printf("\tFlags: 0x%x\n", ptr->ai_flags);
printf("\tFamily: ");
switch (ptr->ai_family) {
case AF_UNSPEC:
printf("Unspecified\n");
break;
case AF_INET:
printf("AF_INET (IPv4)\n");
sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
printf("\tIPv4 address %s\n",
inet_ntoa(sockaddr_ipv4->sin_addr) );
break;
case AF_INET6:
printf("AF_INET6 (IPv6)\n");
// the InetNtop function is available on Windows Vista and later
// sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
// printf("\tIPv6 address %s\n",
// InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstringbuffer, 46) );
// We use WSAAddressToString since it is supported on Windows XP and later
sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
// The buffer length is changed by each call to WSAAddresstoString
// So we need to set it for each iteration through the loop for safety
ipbufferlength = 46;
iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL,
ipstringbuffer, &ipbufferlength );
if (iRetval)
printf("WSAAddressToString failed with %u\n", WSAGetLastError() );
else
printf("\tIPv6 address %s\n", ipstringbuffer);
break;
case AF_NETBIOS:
printf("AF_NETBIOS (NetBIOS)\n");
break;
default:
printf("Other %ld\n", ptr->ai_family);
break;
}
printf("\tSocket type: ");
switch (ptr->ai_socktype) {
case 0:
printf("Unspecified\n");
break;
case SOCK_STREAM:
printf("SOCK_STREAM (stream)\n");
break;
case SOCK_DGRAM:
printf("SOCK_DGRAM (datagram) \n");
break;
case SOCK_RAW:
printf("SOCK_RAW (raw) \n");
break;
case SOCK_RDM:
printf("SOCK_RDM (reliable message datagram)\n");
break;
case SOCK_SEQPACKET:
printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
break;
default:
printf("Other %ld\n", ptr->ai_socktype);
break;
}
printf("\tProtocol: ");
switch (ptr->ai_protocol) {
case 0:
printf("Unspecified\n");
break;
case IPPROTO_TCP:
printf("IPPROTO_TCP (TCP)\n");
break;
case IPPROTO_UDP:
printf("IPPROTO_UDP (UDP) \n");
break;
default:
printf("Other %ld\n", ptr->ai_protocol);
break;
}
printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
printf("\tCanonical name: %s\n", ptr->ai_canonname);
}
freeaddrinfo(result);
WSACleanup();
return 0;
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での定義
#include <windows.h>
// ADDRINFOA (x64 48 / x86 32 バイト)
typedef struct ADDRINFOA {
INT ai_flags;
INT ai_family;
INT ai_socktype;
INT ai_protocol;
UINT_PTR ai_addrlen;
LPSTR ai_canonname;
SOCKADDR* ai_addr;
ADDRINFOA* ai_next;
} ADDRINFOA;using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ADDRINFOA
{
public int ai_flags;
public int ai_family;
public int ai_socktype;
public int ai_protocol;
public UIntPtr ai_addrlen;
public IntPtr ai_canonname;
public IntPtr ai_addr;
public IntPtr ai_next;
}Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure ADDRINFOA
Public ai_flags As Integer
Public ai_family As Integer
Public ai_socktype As Integer
Public ai_protocol As Integer
Public ai_addrlen As UIntPtr
Public ai_canonname As IntPtr
Public ai_addr As IntPtr
Public ai_next As IntPtr
End Structureimport ctypes
from ctypes import wintypes
class ADDRINFOA(ctypes.Structure):
_fields_ = [
("ai_flags", ctypes.c_int),
("ai_family", ctypes.c_int),
("ai_socktype", ctypes.c_int),
("ai_protocol", ctypes.c_int),
("ai_addrlen", ctypes.c_size_t),
("ai_canonname", ctypes.c_void_p),
("ai_addr", ctypes.c_void_p),
("ai_next", ctypes.c_void_p),
]#[repr(C)]
pub struct ADDRINFOA {
pub ai_flags: i32,
pub ai_family: i32,
pub ai_socktype: i32,
pub ai_protocol: i32,
pub ai_addrlen: usize,
pub ai_canonname: *mut core::ffi::c_void,
pub ai_addr: *mut core::ffi::c_void,
pub ai_next: *mut core::ffi::c_void,
}import "golang.org/x/sys/windows"
type ADDRINFOA struct {
ai_flags int32
ai_family int32
ai_socktype int32
ai_protocol int32
ai_addrlen uintptr
ai_canonname uintptr
ai_addr uintptr
ai_next uintptr
}type
ADDRINFOA = record
ai_flags: Integer;
ai_family: Integer;
ai_socktype: Integer;
ai_protocol: Integer;
ai_addrlen: NativeUInt;
ai_canonname: Pointer;
ai_addr: Pointer;
ai_next: Pointer;
end;const ADDRINFOA = extern struct {
ai_flags: i32,
ai_family: i32,
ai_socktype: i32,
ai_protocol: i32,
ai_addrlen: usize,
ai_canonname: ?*anyopaque,
ai_addr: ?*anyopaque,
ai_next: ?*anyopaque,
};type
ADDRINFOA {.bycopy.} = object
ai_flags: int32
ai_family: int32
ai_socktype: int32
ai_protocol: int32
ai_addrlen: uint
ai_canonname: pointer
ai_addr: pointer
ai_next: pointerstruct ADDRINFOA
{
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
void* ai_canonname;
void* ai_addr;
void* ai_next;
}HSP用 定義
HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; ADDRINFOA サイズ: 32 バイト(x86)
dim st, 8 ; 4byte整数×8(構造体サイズ 32 / 4 切り上げ)
; ai_flags : INT (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; ai_family : INT (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; ai_socktype : INT (+8, 4byte) st.2 = 値 / 値 = st.2 (lpoke/lpeek も可)
; ai_protocol : INT (+12, 4byte) st.3 = 値 / 値 = st.3 (lpoke/lpeek も可)
; ai_addrlen : UINT_PTR (+16, 4byte) st.4 = 値 / 値 = st.4 (lpoke/lpeek も可)
; ai_canonname : LPSTR (+20, 4byte) st.5 = 値 / 値 = st.5 (lpoke/lpeek も可)
; ai_addr : SOCKADDR* (+24, 4byte) varptr(st)+24 を基点に操作(4byte:入れ子/配列)
; ai_next : ADDRINFOA* (+28, 4byte) varptr(st)+28 を基点に操作(4byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; ADDRINFOA サイズ: 48 バイト(x64)
dim st, 12 ; 4byte整数×12(構造体サイズ 48 / 4 切り上げ)
; ai_flags : INT (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; ai_family : INT (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; ai_socktype : INT (+8, 4byte) st.2 = 値 / 値 = st.2 (lpoke/lpeek も可)
; ai_protocol : INT (+12, 4byte) st.3 = 値 / 値 = st.3 (lpoke/lpeek も可)
; ai_addrlen : UINT_PTR (+16, 8byte) qpoke st,16,値 / qpeek(st,16) ※IronHSPのみ。3.7/3.8は lpoke st,16,下位 : lpoke st,20,上位
; ai_canonname : LPSTR (+24, 8byte) qpoke st,24,値 / qpeek(st,24) ※IronHSPのみ。3.7/3.8は lpoke st,24,下位 : lpoke st,28,上位
; ai_addr : SOCKADDR* (+32, 8byte) varptr(st)+32 を基点に操作(8byte:入れ子/配列)
; ai_next : ADDRINFOA* (+40, 8byte) varptr(st)+40 を基点に操作(8byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global ADDRINFOA
#field int ai_flags
#field int ai_family
#field int ai_socktype
#field int ai_protocol
#field intptr ai_addrlen
#field intptr ai_canonname
#field intptr ai_addr
#field intptr ai_next
#endstruct
stdim st, ADDRINFOA ; NSTRUCT 変数を確保
st->ai_flags = 100
mes "ai_flags=" + st->ai_flags