Win32 API 日本語リファレンス
ホームNetworking.WinSock › WSAMSG

WSAMSG

構造体
サイズx64: 56 バイト / x86: 28 バイト

サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。

フィールド

フィールドサイズx64x86説明
nameSOCKADDR*8/4+0+0リモートアドレスに関する情報を格納する SOCKET_ADDRESS 構造体へのポインターです。未接続のソケットでのみ使用されます。
namelenINT4+8+4pAddr メンバーが指す SOCKET_ADDRESS 構造体の長さ (バイト単位) です。未接続のソケットでのみ使用されます。
lpBuffersWSABUF*8/4+16+8メッセージデータの受信に使用される WSABUF 構造体の配列です。lpBuffers メンバーは複数のバッファーを保持できるため、スキャッター/ギャザー I/O を使用できます。
dwBufferCountDWORD4+24+12lpBuffers メンバーが指すバッファーの数です。
ControlWSABUF16/8+32+16省略可能な制御データを指定するために使用される WSABUF 型の構造体です。「解説」を参照してください。
dwFlagsDWORD4+48+24

1 つ以上の制御フラグで、値の論理 OR として指定します。入力時に dwFlags メンバーに指定できる値は、Winsock2.h ヘッダーファイルで定義されています。出力時に dwFlags メンバーに設定される値は、Ws2def.h ヘッダーファイル (Winsock2.h ヘッダーファイルから自動的にインクルードされます) で定義されています。

入力時のフラグ 意味
MSG_PEEK
受信データを覗き見します。データはバッファーにコピーされますが、入力キューからは削除されません。このフラグは非オーバーラップソケットでのみ有効です。
返されるフラグ 意味
MSG_BCAST
データグラムがリンク層のブロードキャストとして、またはブロードキャストアドレスである宛先 IP アドレス宛てに受信されました。
MSG_MCAST
データグラムがマルチキャストアドレスである宛先 IP アドレス宛てに受信されました。
MSG_TRUNC
データグラムが切り詰められました。プロセスが確保した領域よりも多くのデータが存在しました。
MSG_CTRUNC
制御 (補助) データが切り詰められました。プロセスが確保した領域よりも多くの制御データが存在しました。

公式ドキュメント

WSAMSG 構造体は、 LPFN_WSARECVMSG (WSARecvMsg) 関数および WSASendMsg 関数と共に使用され、接続済みおよび未接続のソケットに関するアドレスと省略可能な制御情報、ならびにメッセージデータを格納するためのバッファーの配列を保持します。

解説(Remarks)

Microsoft Windows Software Development Kit (SDK) では、Windows Vista で使用するこの構造体のバージョンは、dwBufferCount メンバーと dwFlags メンバーのデータ型が ULONG として定義されています。アプリケーションをコンパイルする際、ターゲットプラットフォームが Windows Vista 以降 (NTDDI_VERSION >= NTDDI_LONGHORN、_WIN32_WINNT >= 0x0600、または WINVER >= 0x0600) である場合、dwBufferCount メンバーと dwFlags メンバーのデータ型は ULONG になります。

Windows Server 2003 および Windows XP: アプリケーションをコンパイルする際、dwBufferCount メンバーと dwFlags メンバーのデータ型は DWORD になります。

Windows Vista 以降向けにリリースされた Windows SDK では、WSAMSG 構造体は Ws2def.h ヘッダーファイルで定義されています。Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用しないでください。

送信中にデータグラムまたは制御データが切り詰められた場合、 WSAMSG 構造体と共に使用している関数は SOCKET_ERROR を返し、 WSAGetLastError 関数の呼び出しは WSAEMSGSIZE を返します。何が切り詰められたのかは、MSG_TRUNC フラグや MSG_CTRUNC フラグを確認してアプリケーションが判断します。

Control メンバーの使用

次の表は、IPv4 および IPv6 で Control メンバーに使用できる制御データのさまざまな用途をまとめたものです。

プロトコル cmsg_level cmsg_type 説明
IPv4 IPPROTO_IP IP_ORIGINAL_ARRIVAL_IF データグラムソケットでパケットを受信した元の IPv4 到着インターフェイスを受け取ります。この制御データは、IPv4 の NAT トラバーサルに Teredo、6to4、または ISATAP トンネルが使用される場合にファイアウォールが使用します。WSAMSG 構造体の cmsg_data[] メンバーは ULONG で、Ifdef.h ヘッダーファイルで定義されている IF_INDEX を格納します。

詳細については、IP_ORIGINAL_ARRIVAL_IF ソケットオプションに関する IPPROTO_IP ソケットオプション を参照してください。

Windows Server 2008、Windows Vista、Windows Server 2003 および Windows XP: IP_ORIGINAL_ARRIVAL_IFcmsg_type はサポートされていません。
IPv4 IPPROTO_IP IP_PKTINFO IPv4 ソケットのパケット情報を指定または受信します。詳細については、IP_PKTINFO ソケットオプションを参照してください。
IPv4 IPPROTO_IP IP_ECN IPv4 ヘッダーの Type of Service (TOS) フィールドの ECN コードポイントを指定または受信します。詳細については、WSASetRecvIPEcn を参照してください。
IPv6 IPPROTO_IPV6 IPV6_DSTOPTS 宛先オプションを指定または受信します。
IPv6 IPPROTO_IPV6 IPV6_HOPLIMIT ホップ制限を指定または受信します。詳細については、IPV6_HOPLIMIT ソケットオプションに関する IPPROTO_IPV6 ソケットオプション を参照してください。
IPv6 IPPROTO_IPV6 IPV6_HOPOPTS ホップバイホップオプションを指定または受信します。
IPv6 IPPROTO_IPV6 IPV6_NEXTHOP ネクストホップアドレスを指定します。
IPv6 IPPROTO_IPV6 IPV6_PKTINFO IPv6 ソケットのパケット情報を指定または受信します。詳細については、IPV6_PKTINFO ソケットオプションを参照してください。
IPv6 IPPROTO_IPV6 IPV6_RTHDR ルーティングヘッダーを指定または受信します。
IPv6 IPPROTO_IPV6 IPV6_ECN IPv6 ヘッダーの Traffic Class フィールドの ECN コードポイントを指定または受信します。詳細については、WSASetRecvIPEcn を参照してください。

制御データは 1 つ以上の制御データオブジェクトで構成され、各オブジェクトは次のように定義される WSACMSGHDR 構造体で始まります。

struct wsacmsghdr {
  UINT        cmsg_len;
  INT         cmsg_level;
  INT         cmsg_type;
  /* followed by UCHAR cmsg_data[] */
} WSACMSGHDR;
WSACMSGHDR 構造体のヘッダー情報は、アプリケーションではなくトランスポートが設定します。アプリケーションは必要なソケットオプションを設定し、十分なバッファーサイズを用意するだけです。

WSACMSGHDR 構造体のメンバーは次のとおりです。

用語 説明
cmsg_len WSACMSGHDR の先頭からデータの末尾までのデータのバイト数です (データの後に続く可能性のあるパディングバイトは含みません)。
cmsg_level 制御情報の発信元となったプロトコルです。
cmsg_type プロトコル固有の制御情報の種類です。

データオブジェクトをたどるには、次のマクロを使用します。


#define LPCMSGHDR *WSA_CMSG_FIRSTHDR(LPWSAMSG msg);

最初の制御データオブジェクトへのポインターを返します。Control メンバーが NULL ポインターである場合など、 WSAMSG 構造体に制御データが存在しない場合は NULL ポインターを返します。


#define LPCMSGHDR *WSA_CMSG_NXTHDR(LPWSAMSG msg, LPWSACMSGHDR cmsg);

次の制御データオブジェクトへのポインターを返します。データオブジェクトがこれ以上存在しない場合は NULL を返します。pcmsg パラメーターが NULL の場合は、最初の制御データオブジェクトへのポインターを返します。


#define UCHAR *WSA_CMSG_DATA(LPWSACMSGHDR pcmsg);

データの先頭バイトへのポインターを返します (構造体では定義されていませんが、cmsg_data メンバーと呼ばれます)。


#define UINT WSA_CMSG_SPACE(UINT length);

データ量を指定すると、制御データオブジェクトの合計サイズを返します。適切なバッファー領域を割り当てるために使用します。アラインメント用のパディングを含みます。


#define UINT WSA_CMSG_LEN(UINT length);

データ量を指定すると、cmsg_len に設定すべき値を返します。アラインメント用のパディングを含みます。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での定義

#include <windows.h>

// WSABUF  (x64 16 / x86 8 バイト)
typedef struct WSABUF {
    DWORD len;
    LPSTR buf;
} WSABUF;

// WSAMSG  (x64 56 / x86 28 バイト)
typedef struct WSAMSG {
    SOCKADDR* name;
    INT namelen;
    WSABUF* lpBuffers;
    DWORD dwBufferCount;
    WSABUF Control;
    DWORD dwFlags;
} WSAMSG;
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WSABUF
{
    public uint len;
    public IntPtr buf;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WSAMSG
{
    public IntPtr name;
    public int namelen;
    public IntPtr lpBuffers;
    public uint dwBufferCount;
    public WSABUF Control;
    public uint dwFlags;
}
Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure WSABUF
    Public len As UInteger
    Public buf As IntPtr
End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure WSAMSG
    Public name As IntPtr
    Public namelen As Integer
    Public lpBuffers As IntPtr
    Public dwBufferCount As UInteger
    Public Control As WSABUF
    Public dwFlags As UInteger
End Structure
import ctypes
from ctypes import wintypes

class WSABUF(ctypes.Structure):
    _fields_ = [
        ("len", wintypes.DWORD),
        ("buf", ctypes.c_void_p),
    ]

class WSAMSG(ctypes.Structure):
    _fields_ = [
        ("name", ctypes.c_void_p),
        ("namelen", ctypes.c_int),
        ("lpBuffers", ctypes.c_void_p),
        ("dwBufferCount", wintypes.DWORD),
        ("Control", WSABUF),
        ("dwFlags", wintypes.DWORD),
    ]
#[repr(C)]
pub struct WSABUF {
    pub len: u32,
    pub buf: *mut core::ffi::c_void,
}

#[repr(C)]
pub struct WSAMSG {
    pub name: *mut core::ffi::c_void,
    pub namelen: i32,
    pub lpBuffers: *mut core::ffi::c_void,
    pub dwBufferCount: u32,
    pub Control: WSABUF,
    pub dwFlags: u32,
}
import "golang.org/x/sys/windows"

type WSABUF struct {
	len uint32
	buf uintptr
}

type WSAMSG struct {
	name uintptr
	namelen int32
	lpBuffers uintptr
	dwBufferCount uint32
	Control WSABUF
	dwFlags uint32
}
type
  WSABUF = record
    len: DWORD;
    buf: Pointer;
  end;

  WSAMSG = record
    name: Pointer;
    namelen: Integer;
    lpBuffers: Pointer;
    dwBufferCount: DWORD;
    Control: WSABUF;
    dwFlags: DWORD;
  end;
const WSABUF = extern struct {
    len: u32,
    buf: ?*anyopaque,
};

const WSAMSG = extern struct {
    name: ?*anyopaque,
    namelen: i32,
    lpBuffers: ?*anyopaque,
    dwBufferCount: u32,
    Control: WSABUF,
    dwFlags: u32,
};
type
  WSABUF {.bycopy.} = object
    len: uint32
    buf: pointer

  WSAMSG {.bycopy.} = object
    name: pointer
    namelen: int32
    lpBuffers: pointer
    dwBufferCount: uint32
    Control: WSABUF
    dwFlags: uint32
struct WSABUF
{
    uint len;
    void* buf;
}

struct WSAMSG
{
    void* name;
    int namelen;
    void* lpBuffers;
    uint dwBufferCount;
    WSABUF Control;
    uint dwFlags;
}

HSP用 定義

HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。

; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; WSAMSG サイズ: 28 バイト(x86)
dim st, 7    ; 4byte整数×7(構造体サイズ 28 / 4 切り上げ)
; name : SOCKADDR* (+0, 4byte)  varptr(st)+0 を基点に操作(4byte:入れ子/配列)
; namelen : INT (+4, 4byte)  st.1 = 値  /  値 = st.1   (lpoke/lpeek も可)
; lpBuffers : WSABUF* (+8, 4byte)  varptr(st)+8 を基点に操作(4byte:入れ子/配列)
; dwBufferCount : DWORD (+12, 4byte)  st.3 = 値  /  値 = st.3   (lpoke/lpeek も可)
; Control : WSABUF (+16, 8byte)  varptr(st)+16 を基点に操作(8byte:入れ子/配列)
; dwFlags : DWORD (+24, 4byte)  st.6 = 値  /  値 = st.6   (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; WSAMSG サイズ: 56 バイト(x64)
dim st, 14    ; 4byte整数×14(構造体サイズ 56 / 4 切り上げ)
; name : SOCKADDR* (+0, 8byte)  varptr(st)+0 を基点に操作(8byte:入れ子/配列)
; namelen : INT (+8, 4byte)  st.2 = 値  /  値 = st.2   (lpoke/lpeek も可)
; lpBuffers : WSABUF* (+16, 8byte)  varptr(st)+16 を基点に操作(8byte:入れ子/配列)
; dwBufferCount : DWORD (+24, 4byte)  st.6 = 値  /  値 = st.6   (lpoke/lpeek も可)
; Control : WSABUF (+32, 16byte)  varptr(st)+32 を基点に操作(16byte:入れ子/配列)
; dwFlags : DWORD (+48, 4byte)  st.12 = 値  /  値 = st.12   (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
; ※GUID・入れ子構造体はデフォルト型でないため、依存する #defstruct を先に定義(下記に同梱)。
#defstruct global WSABUF
    #field int len
    #field intptr buf
#endstruct

#defstruct global WSAMSG
    #field intptr name
    #field int namelen
    #field intptr lpBuffers
    #field int dwBufferCount
    #field WSABUF Control
    #field int dwFlags
#endstruct

stdim st, WSAMSG        ; NSTRUCT 変数を確保
st->namelen = 100
mes "namelen=" + st->namelen