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

WSASocketA

関数
プロトコル情報やフラグを指定してソケットを作成する。
DLLWS2_32.dll文字セットANSI (-A)呼出規約winapiSetLastErrorあり対応OSWindows 8.1 以降

シグネチャ

// WS2_32.dll  (ANSI / -A)
#include <windows.h>

SOCKET WSASocketA(
    INT af,
    INT type,
    INT protocol,
    WSAPROTOCOL_INFOA* lpProtocolInfo,   // optional
    DWORD g,
    DWORD dwFlags
);

パラメーター

名前方向説明
afINTin

アドレスファミリーの指定。アドレスファミリーに指定可能な値は Winsock2.h ヘッダーファイルで定義されています。

Windows Vista 以降向けにリリースされた Windows SDK では、ヘッダーファイルの構成が変更され、アドレスファミリーに指定可能な値は Ws2def.h ヘッダーファイルで定義されています。なお、Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用してはなりません。

現在サポートされている値は AF_INET または AF_INET6 で、これらはそれぞれ IPv4 と IPv6 のインターネット アドレスファミリー形式です。アドレスファミリーのその他のオプション(例えば NetBIOS で使用する AF_NETBIOS など)は、そのアドレスファミリー用の Windows Sockets サービスプロバイダーがインストールされている場合にサポートされます。なお、AF_ アドレスファミリー定数と PF_ プロトコルファミリー定数の値は同一であるため(例えば AF_INETPF_INET)、どちらの定数も使用できます。

以下の表はアドレスファミリーの一般的な値を示しますが、これ以外にも多くの値が指定可能です。

Af 意味
AF_UNSPEC
0
アドレスファミリーは未指定です。
AF_INET
2
Internet Protocol version 4 (IPv4) アドレスファミリーです。
AF_IPX
6
IPX/SPX アドレスファミリーです。このアドレスファミリーは、NWLink IPX/SPX NetBIOS 互換トランスポートプロトコルがインストールされている場合にのみサポートされます。

このアドレスファミリーは Windows Vista 以降ではサポートされません。

AF_APPLETALK
16
AppleTalk アドレスファミリーです。このアドレスファミリーは、AppleTalk プロトコルがインストールされている場合にのみサポートされます。

このアドレスファミリーは Windows Vista 以降ではサポートされません。

AF_NETBIOS
17
NetBIOS アドレスファミリーです。このアドレスファミリーは、NetBIOS 用の Windows Sockets プロバイダーがインストールされている場合にのみサポートされます。

NetBIOS 用の Windows Sockets プロバイダーは 32 ビット版の Windows でサポートされます。このプロバイダーは 32 ビット版の Windows では既定でインストールされます。

NetBIOS 用の Windows Sockets プロバイダーは、Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP を含む 64 ビット版の Windows ではサポートされません。

NetBIOS 用の Windows Sockets プロバイダーは、type パラメーターが SOCK_DGRAM に設定されたソケットのみをサポートします。

NetBIOS 用の Windows Sockets プロバイダーは、NetBIOS プログラミングインターフェイスとは直接の関係はありません。NetBIOS プログラミングインターフェイスは Windows Vista、Windows Server 2008 以降ではサポートされません。

AF_INET6
23
Internet Protocol version 6 (IPv6) アドレスファミリーです。
AF_IRDA
26
Infrared Data Association (IrDA) アドレスファミリーです。

このアドレスファミリーは、コンピューターに赤外線ポートとドライバーがインストールされている場合にのみサポートされます。

AF_BTH
32
Bluetooth アドレスファミリーです。

このアドレスファミリーは、コンピューターに Bluetooth アダプターとドライバーがインストールされている場合、Windows XP with SP2 以降でサポートされます。

typeINTin

新しいソケットの種類の指定。

ソケットの種類に指定可能な値は Winsock2.h ヘッダーファイルで定義されています。

以下の表は、Windows Sockets 2 でサポートされる type パラメーターに指定可能な値を示します。

Type 意味
SOCK_STREAM
1
順序付けされた、信頼性のある、双方向の、接続ベースのバイトストリームを、OOB データ転送機構とともに提供するソケットの種類です。このソケットの種類は、インターネットアドレスファミリー(AF_INET または AF_INET6)では Transmission Control Protocol (TCP) を使用します。
SOCK_DGRAM
2
データグラムをサポートするソケットの種類です。データグラムは、コネクションレスで、信頼性がなく、固定の(通常は小さい)最大長を持つバッファーです。このソケットの種類は、インターネットアドレスファミリー(AF_INET または AF_INET6)では User Datagram Protocol (UDP) を使用します。
SOCK_RAW
3
アプリケーションが次の上位層プロトコルヘッダーを操作できる raw ソケットを提供するソケットの種類です。IPv4 ヘッダーを操作するには、ソケットに IP_HDRINCL ソケットオプションを設定する必要があります。IPv6 ヘッダーを操作するには、ソケットに IPV6_HDRINCL ソケットオプションを設定する必要があります。
SOCK_RDM
4
信頼性のあるメッセージデータグラムを提供するソケットの種類です。この種類の例として、Windows における Pragmatic General Multicast (PGM) マルチキャストプロトコルの実装があり、しばしば reliable multicast programming と呼ばれます。

この type 値は、Reliable Multicast Protocol がインストールされている場合にのみサポートされます。

SOCK_SEQPACKET
5
データグラムに基づく疑似ストリームパケットを提供するソケットの種類です。

Windows Sockets 2 では、新しいソケットの種類が導入されました。アプリケーションは、 WSAEnumProtocols 関数を通じて、利用可能な各トランスポートプロトコルの属性を動的に検出できます。これにより、アプリケーションはあるアドレスファミリーで指定可能なソケットの種類とプロトコルのオプションを判別し、この情報をこのパラメーターの指定時に利用できます。Winsock2.h および Ws2def.h ヘッダーファイル内のソケットの種類の定義は、新しいソケットの種類、アドレスファミリー、プロトコルが定義されるに従い、定期的に更新されます。

Windows Sockets 1.1 では、指定可能なソケットの種類は SOCK_DGRAMSOCK_STREAM のみです。

protocolINTin

使用するプロトコル。protocol パラメーターに指定可能なオプションは、指定したアドレスファミリーとソケットの種類に固有です。protocol に指定可能な値は Winsock2.h および Wsrm.h ヘッダーファイルで定義されています。

Windows Vista 以降向けにリリースされた Windows SDK では、ヘッダーファイルの構成が変更され、このパラメーターには Ws2def.h ヘッダーファイルで定義された IPPROTO 列挙型の値のいずれかを指定できます。なお、Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用してはなりません。

値 0 を指定した場合、呼び出し元はプロトコルを指定せず、サービスプロバイダーが使用する protocol を選択します。

af パラメーターが AF_INET または AF_INET6 で、typeSOCK_RAW の場合、protocol に指定した値は IPv6 または IPv4 パケットヘッダーのプロトコルフィールドに設定されます。

以下の表は protocol の一般的な値を示しますが、これ以外にも多くの値が指定可能です。

protocol 意味
IPPROTO_ICMP
1
Internet Control Message Protocol (ICMP) です。これは、af パラメーターが AF_UNSPECAF_INET、または AF_INET6 で、type パラメーターが SOCK_RAW または未指定の場合に指定可能な値です。

この protocol 値は Windows XP 以降でサポートされます。

IPPROTO_IGMP
2
Internet Group Management Protocol (IGMP) です。これは、af パラメーターが AF_UNSPECAF_INET、または AF_INET6 で、type パラメーターが SOCK_RAW または未指定の場合に指定可能な値です。

この protocol 値は Windows XP 以降でサポートされます。

BTHPROTO_RFCOMM
3
Bluetooth Radio Frequency Communications (Bluetooth RFCOMM) プロトコルです。これは、af パラメーターが AF_BTH で、type パラメーターが SOCK_STREAM の場合に指定可能な値です。

この protocol 値は Windows XP with SP2 以降でサポートされます。

IPPROTO_TCP
6
Transmission Control Protocol (TCP) です。これは、af パラメーターが AF_INET または AF_INET6 で、type パラメーターが SOCK_STREAM の場合に指定可能な値です。
IPPROTO_UDP
17
User Datagram Protocol (UDP) です。これは、af パラメーターが AF_INET または AF_INET6 で、type パラメーターが SOCK_DGRAM の場合に指定可能な値です。
IPPROTO_ICMPV6
58
Internet Control Message Protocol Version 6 (ICMPv6) です。これは、af パラメーターが AF_UNSPECAF_INET、または AF_INET6 で、type パラメーターが SOCK_RAW または未指定の場合に指定可能な値です。

この protocol 値は Windows XP 以降でサポートされます。

IPPROTO_RM
113
信頼性のあるマルチキャスト用の PGM プロトコルです。これは、af パラメーターが AF_INET で、type パラメーターが SOCK_RDM の場合に指定可能な値です。Windows Vista 以降向けにリリースされた Windows SDK では、このプロトコルは IPPROTO_PGM とも呼ばれます。

この protocol 値は、Reliable Multicast Protocol がインストールされている場合にのみサポートされます。

lpProtocolInfoWSAPROTOCOL_INFOA*inoptional作成するソケットの特性を定義する WSAPROTOCOL_INFO 構造体へのポインター。このパラメーターが NULL でない場合、ソケットは指定された WSAPROTOCOL_INFO 構造体に関連付けられたプロバイダーにバインドされます。
gDWORDin

既存のソケットグループ ID、または新しいソケットと新しいソケットグループを作成する際に行う適切なアクション。

g が既存のソケットグループ ID の場合、このグループが設定するすべての要件が満たされていれば、新しいソケットをこのソケットグループに参加させます。

g が既存のソケットグループ ID でない場合、以下の値が指定可能です。

g 意味
0
グループ操作は実行されません。
SG_UNCONSTRAINED_GROUP
0x01
制約のないソケットグループを作成し、新しいソケットを最初のメンバーにします。制約のないグループでは、Winsock はソケットグループ内のすべてのソケットが type および protocol パラメーターに同じ値で作成されていることを強制しません。
SG_CONSTRAINED_GROUP
0x02
制約のあるソケットグループを作成し、新しいソケットを最初のメンバーにします。制約のあるソケットグループでは、Winsock はソケットグループ内のすべてのソケットが type および protocol パラメーターに同じ値で作成されていることを強制します。制約のあるソケットグループはコネクション指向のソケットのみで構成でき、グループ化されたすべてのソケットの接続が同一ホスト上の同一アドレスに対するものであることを要求します。
Note SG_UNCONSTRAINED_GROUP および SG_CONSTRAINED_GROUP 定数は、現在のところパブリックなヘッダーファイルでは定義されていません。
dwFlagsDWORDin

追加のソケット属性を指定するために使用するフラグのセット。

これらのフラグは組み合わせて設定できますが、一部の組み合わせは許可されません。

意味
WSA_FLAG_OVERLAPPED
0x01
オーバーラップ I/O 操作をサポートするソケットを作成します。

ほとんどのソケットはこのフラグを設定して作成すべきです。オーバーラップソケットは、オーバーラップ I/O 操作のために WSASendWSASendToWSARecvWSARecvFromWSAIoctl を利用でき、複数の操作を同時に開始し、進行させることができます。

オーバーラップ操作を許可するすべての関数(WSASendWSARecvWSASendToWSARecvFromWSAIoctl)は、オーバーラップ操作に関連するパラメーターの値が NULL である場合、オーバーラップソケット上での非オーバーラップ使用もサポートします。

WSA_FLAG_MULTIPOINT_C_ROOT
0x02
マルチポイントセッションにおいて c_root となるソケットを作成します。

この属性は、ソケットを作成するトランスポートプロバイダーの WSAPROTOCOL_INFO 構造体がマルチポイントまたはマルチキャスト機構をサポートし、マルチポイントセッションのコントロールプレーンがルート型である場合にのみ許可されます。これは、WSAPROTOCOL_INFO 構造体の dwServiceFlags1 メンバーに XP1_SUPPORT_MULTIPOINT および XP1_MULTIPOINT_CONTROL_PLANE フラグが設定されていることで示されます。

lpProtocolInfo パラメーターが NULL でない場合、トランスポートプロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターによって指し示されます。lpProtocolInfo パラメーターが NULL の場合、WSAPROTOCOL_INFO 構造体は、aftypeprotocol パラメーターに指定された値によって選択されたトランスポートプロバイダーに基づきます。

マルチポイントセッションに関する追加情報については、 Multipoint and Multicast Semantics を参照してください。

WSA_FLAG_MULTIPOINT_C_LEAF
0x04
マルチポイントセッションにおいて c_leaf となるソケットを作成します。

この属性は、ソケットを作成するトランスポートプロバイダーの WSAPROTOCOL_INFO 構造体がマルチポイントまたはマルチキャスト機構をサポートし、マルチポイントセッションのコントロールプレーンが非ルート型である場合にのみ許可されます。これは、WSAPROTOCOL_INFO 構造体の dwServiceFlags1 メンバーに XP1_SUPPORT_MULTIPOINT フラグが設定され、XP1_MULTIPOINT_CONTROL_PLANE フラグが設定されていないことで示されます。

lpProtocolInfo パラメーターが NULL でない場合、トランスポートプロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターによって指し示されます。lpProtocolInfo パラメーターが NULL の場合、WSAPROTOCOL_INFO 構造体は、aftypeprotocol パラメーターに指定された値によって選択されたトランスポートプロバイダーに基づきます。

マルチポイントセッションに関する追加情報については、 Multipoint and Multicast Semantics を参照してください。

WSA_FLAG_MULTIPOINT_D_ROOT
0x08
マルチポイントセッションにおいて d_root となるソケットを作成します。

この属性は、ソケットを作成するトランスポートプロバイダーの WSAPROTOCOL_INFO 構造体がマルチポイントまたはマルチキャスト機構をサポートし、マルチポイントセッションのデータプレーンがルート型である場合にのみ許可されます。これは、WSAPROTOCOL_INFO 構造体の dwServiceFlags1 メンバーに XP1_SUPPORT_MULTIPOINT および XP1_MULTIPOINT_DATA_PLANE フラグが設定されていることで示されます。

lpProtocolInfo パラメーターが NULL でない場合、トランスポートプロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターによって指し示されます。lpProtocolInfo パラメーターが NULL の場合、WSAPROTOCOL_INFO 構造体は、aftypeprotocol パラメーターに指定された値によって選択されたトランスポートプロバイダーに基づきます。

マルチポイントセッションに関する追加情報については、 Multipoint and Multicast Semantics を参照してください。

WSA_FLAG_MULTIPOINT_D_LEAF
0x10
マルチポイントセッションにおいて d_leaf となるソケットを作成します。

この属性は、ソケットを作成するトランスポートプロバイダーの WSAPROTOCOL_INFO 構造体がマルチポイントまたはマルチキャスト機構をサポートし、マルチポイントセッションのデータプレーンが非ルート型である場合にのみ許可されます。これは、WSAPROTOCOL_INFO 構造体の dwServiceFlags1 メンバーに XP1_SUPPORT_MULTIPOINT フラグが設定され、XP1_MULTIPOINT_DATA_PLANE フラグが設定されていないことで示されます。

lpProtocolInfo パラメーターが NULL でない場合、トランスポートプロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターによって指し示されます。lpProtocolInfo パラメーターが NULL の場合、WSAPROTOCOL_INFO 構造体は、aftypeprotocol パラメーターに指定された値によって選択されたトランスポートプロバイダーに基づきます。

マルチポイントセッションに関する追加情報については、 Multipoint and Multicast Semantics を参照してください。

WSA_FLAG_ACCESS_SYSTEM_SECURITY
0x40
任意アクセス制御リスト (DACL) だけでなく、システムアクセス制御リスト (SACL) を含むセキュリティ記述子をソケットに設定できるソケットを作成します。

SACL は、オブジェクトに対するアクセスチェックが発生した際に監査やアラームを生成するために使用されます。ソケットの場合、bind 関数に指定された特定のアドレスにソケットのバインドを許可すべきかを判定するために、アクセスチェックが発生します。

ACCESS_SYSTEM_SECURITY アクセス権は、オブジェクトのセキュリティ記述子内の SACL を取得または設定する能力を制御します。システムは、要求元スレッドのアクセストークンで SE_SECURITY_NAME 特権が有効になっている場合にのみ、このアクセス権を付与します。

WSA_FLAG_NO_HANDLE_INHERIT
0x80
継承不可のソケットを作成します。

WSASocket 関数または socket 関数によって作成されたソケットハンドルは、既定で継承可能です。このフラグを設定すると、ソケットハンドルは継承不可になります。

GetHandleInformation 関数を使用して、ソケットハンドルが WSA_FLAG_NO_HANDLE_INHERIT フラグを設定して作成されたかどうかを判定できます。GetHandleInformation 関数は、HANDLE_FLAG_INHERIT 値が設定されているかどうかを返します。

このフラグは Windows 7 with SP1、Windows Server 2008 R2 with SP1 以降でサポートされます。

Important マルチポイントソケットでは、WSA_FLAG_MULTIPOINT_C_ROOT または WSA_FLAG_MULTIPOINT_C_LEAF フラグのうち 1 つだけを指定でき、WSA_FLAG_MULTIPOINT_D_ROOT または WSA_FLAG_MULTIPOINT_D_LEAF フラグのうち 1 つだけを指定できます。追加情報については Multipoint and Multicast Semantics を参照してください。

戻り値の型: SOCKET

公式ドキュメント

WSASocket 関数は、特定のトランスポートサービスプロバイダーにバインドされたソケットを作成します。(ANSI)

戻り値

エラーが発生しない場合、 WSASocket は新しいソケットを参照するディスクリプターを返します。それ以外の場合、INVALID_SOCKET の値が返され、 WSAGetLastError を呼び出すことで具体的なエラーコードを取得できます。

Note このエラーコードの説明は Microsoft 固有のものです。
エラーコード 意味
WSANOTINITIALISED
この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。
WSAENETDOWN
ネットワークサブシステムが失敗しました。
WSAEAFNOSUPPORT
指定されたアドレスファミリーはサポートされていません。
WSAEFAULT
lpProtocolInfo パラメーターがプロセスのアドレス空間の有効な部分にありません。
WSAEINPROGRESS
ブロッキングの Windows Sockets 1.1 呼び出しが進行中であるか、サービスプロバイダーがコールバック関数をまだ処理中です。
WSAEINVAL
この値は以下のいずれかの条件で true になります。
  • 指定された g パラメーターが有効ではありません。
  • lpProtocolInfo が指す WSAPROTOCOL_INFO 構造体が不完全であるか、内容が無効であるか、 WSAPROTOCOL_INFO 構造体が以前の複製ソケット操作で既に使用されています。
  • ソケットトリプル <aftypeprotocol> のメンバーに指定された値は個別にはサポートされていますが、指定された組み合わせはサポートされていません。
WSAEINVALIDPROVIDER
サービスプロバイダーが 2.2 以外のバージョンを返しました。
WSAEINVALIDPROCTABLE
サービスプロバイダーが WSPStartup に対して無効または不完全なプロシージャテーブルを返しました。
WSAEMFILE
これ以上利用可能なソケットディスクリプターがありません。
WSAENOBUFS
利用可能なバッファー空間がありません。ソケットを作成できません。
WSAEPROTONOSUPPORT
指定されたプロトコルはサポートされていません。
WSAEPROTOTYPE
指定されたプロトコルはこのソケットに対して誤った種類です。
WSAEPROVIDERFAILEDINIT
サービスプロバイダーの初期化に失敗しました。このエラーは、レイヤードサービスプロバイダー (LSP) または名前空間プロバイダーが正しくインストールされていないか、プロバイダーが正しく動作しない場合に返されます。
WSAESOCKTNOSUPPORT
指定されたソケットの種類はこのアドレスファミリーではサポートされていません。

解説(Remarks)

WSASocket 関数は、ソケットディスクリプターと関連リソースを割り当て、トランスポートサービスプロバイダーに関連付けます。ほとんどのソケットは、dwFlags パラメーターに WSA_FLAG_OVERLAPPED 属性を設定して作成すべきです。この属性を設定して作成されたソケットは、より高いパフォーマンスを提供するオーバーラップ I/O 操作の使用をサポートします。既定では、WSASocket 関数で作成されたソケットにはこのオーバーラップ属性は設定されません。これに対し、socket 関数は、既定の動作としてオーバーラップ I/O 操作をサポートするソケットを作成します。

lpProtocolInfo パラメーターが NULL の場合、Winsock は、aftypeprotocol パラメーターで指定されたアドレスファミリー、ソケットの種類、プロトコルの要求された組み合わせをサポートする、最初に利用可能なトランスポートサービスプロバイダーを利用します。

lpProtocolInfo パラメーターが NULL でない場合、ソケットは指定された WSAPROTOCOL_INFO 構造体に関連付けられたプロバイダーにバインドされます。この場合、アプリケーションは aftypeprotocol のいずれのパラメーターの値としても、マニフェスト定数 FROM_PROTOCOL_INFO を指定できます。これは、指定された WSAPROTOCOL_INFO 構造体の対応する値(iAddressFamilyiSocketTypeiProtocol)を想定することを示します。いずれの場合も、aftypeprotocol に指定された値は変更されずにトランスポートサービスプロバイダーに渡されます。

aftypeprotocol に基づいてプロトコルとそれをサポートするサービスプロバイダーを選択する際、この手順はベースプロトコルまたはプロトコルチェーンのみを選択し、プロトコルレイヤー単独を選択することはありません。連結されていないプロトコルレイヤーは、typeaf に部分一致するとも見なされません。すなわち、適切なプロトコルが見つからない場合でも、それらは WSAEAFNOSUPPORTWSAEPROTONOSUPPORT のエラーコードにはつながりません。

Note マニフェスト定数 AF_UNSPEC は引き続きヘッダーファイルで定義されていますが、その使用は強く推奨されません。protocol パラメーターの値の解釈にあいまいさを生じさせる可能性があるためです。
アプリケーションは、af パラメーターに AF_INET6 を使用し、IPv4 と IPv6 の両方で使用できるデュアルモードソケットを作成することが推奨されます。

WSASocket 関数を使用してソケットを作成する場合、SO_RCVTIMEO または SO_SNDTIMEO ソケットオプションが正しく機能するためには、dwFlags パラメーターに WSA_FLAG_OVERLAPPED 属性を設定する必要があります。そうしないと、タイムアウトがソケットに対して有効になりません。

SOCK_STREAM などのコネクション指向のソケットは全二重接続を提供し、データを送受信する前に接続状態になっている必要があります。指定されたソケットへの接続は、 connect または WSAConnect 関数の呼び出しによって確立されます。接続後は、 send/WSASend および recv/WSARecv の呼び出しを使用してデータを転送できます。セッションが完了したら、ソケットに関連付けられたリソースを解放するために closesocket 関数を呼び出すべきです。コネクション指向のソケットでは、closesocket 関数を呼び出す前に、ソケット上のデータ転送を停止するために shutdown 関数を呼び出すべきです。

信頼性のあるコネクション指向のソケットを実装するために使用される通信プロトコルは、データが失われたり重複したりしないことを保証します。ピアプロトコルがバッファー空間を持つデータを妥当な時間内に正常に送信できない場合、接続は切断されたと見なされ、以降の呼び出しはエラーコードが WSAETIMEDOUT に設定されて失敗します。

コネクションレスでメッセージ指向のソケットでは、 sendto/WSASendTo および recvfrom/WSARecvFrom を使用して、任意のピアとの間でデータグラムを送受信できます。そのようなソケットが特定のピアに接続されている場合、 send/WSASend を使用してそのピアにデータグラムを送信でき、 recv/WSARecv を使用して(そのピアからのみ)受信できます。

SOCK_RAW の種類を持つソケットのサポートは必須ではありませんが、サービスプロバイダーは可能な限り raw ソケットをサポートすることが推奨されます。

WSASocket 関数を使用して、サービスが使用するソケットを作成することで、別のソケットがそのサービスで使用されているポートと同じポートにバインドしようとした場合に監査レコードを生成できます。このオプションを有効にするには、アプリケーションは以下を行う必要があります。

ACCESS_SYSTEM_SECURITY の詳細については、Authorization のドキュメントの SACL Access Right および Audit Generation を参照してください。

Socket Groups

WinSock 2 では、アプリケーションまたは協調するアプリケーションのセットが、特定のソケットのセットが関連していることと、そうして形成されたグループが特定の属性を持つことを、基盤となるサービスプロバイダーに示すための手段として、ソケットグループという概念が導入されました。グループ属性には、グループ内の個々のソケットの相対的な優先順位や、グループの quality of service 仕様が含まれます。

ネットワーク上でマルチメディアストリームを交換する必要があるアプリケーションは、ソケットのセット間に特定の関係を確立できることが有益となる一例です。ソケットグループをどのように扱うかはトランスポート次第です。

WSASocket および WSAAccept 関数を使用して、新しいソケットを作成する際に明示的にソケットグループを作成し、参加させることができます。ソケットのソケットグループ ID は、getsockopt 関数で level パラメーターを SOL_SOCKET に、optname パラメーターを SO_GROUP_ID に設定することで取得できます。ソケットグループとそれに関連付けられたソケットグループ ID は、このソケットグループに属する最後のソケットが閉じられるまで有効なままです。ソケットグループ ID は、特定のサービスプロバイダーに対してすべてのプロセスにわたって一意です。ソケットグループが 0 の場合、そのソケットはソケットグループのメンバーではないことを示します。

ソケットグループの相対グループ優先順位は、getsockopt 関数で level パラメーターを SOL_SOCKET に、optname パラメーターを SO_GROUP_PRIORITY に設定することでアクセスできます。ソケットグループの相対グループ優先順位は、setsockoptlevel パラメーターを SOL_SOCKET に、optname パラメーターを SO_GROUP_PRIORITY に設定することで設定できます。

Windows に含まれる Winsock プロバイダーはソケットグループの作成を許可し、SG_CONSTRAINED_GROUP を強制します。制約のあるソケットグループ内のすべてのソケットは、type および protocol パラメーターに同じ値で作成される必要があります。制約のあるソケットグループはコネクション指向のソケットのみで構成でき、グループ化されたすべてのソケットの接続が同一ホスト上の同一アドレスに対するものであることを要求します。これが、Windows に含まれる Winsock プロバイダーがソケットグループに適用する唯一の制限です。ソケットグループの優先順位は、Windows に含まれる Winsock プロバイダーや TCP/IP スタックでは現在使用されていません。

Example Code

次の例は、WSASocket 関数の使用方法を示します。
#ifndef UNICODE
#define UNICODE 1
#endif

// link with Ws2_32.lib
#pragma comment(lib,"Ws2_32.lib")

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>   // Needed for _wtoi


int __cdecl wmain(int argc, wchar_t **argv)
{

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData = {0};
    int iResult = 0;

//    int i = 1;

    SOCKET sock = INVALID_SOCKET;
    int iFamily = AF_UNSPEC;
    int iType = 0;
    int iProtocol = 0;
    DWORD dwFlags = 0;

    // Validate the parameters
    if (argc != 5) {
        wprintf(L"usage: %s <addressfamily> <type> <protocol> <flags>\n", argv[0]);
        wprintf(L"       opens a socket for the specified family, type, protocol, and flags\n");
        wprintf(L"       flags value must be in decimal, not hex\n");
        wprintf(L"%ws example usage\n", argv[0]);
        wprintf(L"   %ws 0 2 17 1\n", argv[0]);
        wprintf(L"   where AF_UNSPEC=0 SOCK_DGRAM=2 IPPROTO_UDP=17 OVERLAPPED\n", argv[0]);
        return 1;
    }

    iFamily = _wtoi(argv[1]);
    iType = _wtoi(argv[2]);
    iProtocol = _wtoi(argv[3]);
    dwFlags = _wtoi(argv[4]);
    
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        wprintf(L"WSAStartup failed: %d\n", iResult);
        return 1;
    }

    wprintf(L"Calling socket with following parameters:\n");
    wprintf(L"  Address Family = ");
    switch (iFamily) {
    case AF_UNSPEC:
        wprintf(L"Unspecified");
        break;
    case AF_INET:
        wprintf(L"AF_INET (IPv4)");
        break;
    case AF_INET6:
        wprintf(L"AF_INET6 (IPv6)");
        break;
    case AF_NETBIOS:
        wprintf(L"AF_NETBIOS (NetBIOS)");
        break;
    case AF_BTH:
        wprintf(L"AF_BTH (Bluetooth)");
        break;
    default:
        wprintf(L"Other");
        break;
    }
    wprintf(L" (%d)\n", iFamily);
    
    wprintf(L"  Socket type = ");
    switch (iType) {
    case 0:
        wprintf(L"Unspecified");
        break;
    case SOCK_STREAM:
        wprintf(L"SOCK_STREAM (stream)");
        break;
    case SOCK_DGRAM:
        wprintf(L"SOCK_DGRAM (datagram)");
        break;
    case SOCK_RAW:
        wprintf(L"SOCK_RAW (raw)");
        break;
    case SOCK_RDM:
        wprintf(L"SOCK_RDM (reliable message datagram)");
        break;
    case SOCK_SEQPACKET:
        wprintf(L"SOCK_SEQPACKET (pseudo-stream packet)");
        break;
    default:
        wprintf(L"Other");
        break;
    }
    wprintf(L" (%d)\n", iType);

    wprintf(L"  Protocol = %d = ", iProtocol);
    switch (iProtocol) {
    case 0:
        wprintf(L"Unspecified");
        break;
    case IPPROTO_ICMP:
        wprintf(L"IPPROTO_ICMP (ICMP)");
        break;
    case IPPROTO_IGMP:
        wprintf(L"IPPROTO_IGMP (IGMP)");
        break;
    case IPPROTO_TCP:
        wprintf(L"IPPROTO_TCP (TCP)");
        break;
    case IPPROTO_UDP:
        wprintf(L"IPPROTO_UDP (UDP)");
        break;
    case IPPROTO_ICMPV6:
        wprintf(L"IPPROTO_ICMPV6 (ICMP Version 6)");
        break;
    default:
        wprintf(L"Other");
        break;
    }
    wprintf(L" (%d)\n", iProtocol);

    wprintf(L"  Flags = ");
    if (dwFlags & WSA_FLAG_OVERLAPPED)
        wprintf(L"  WSA_FLAG_OVERLAPPED");
    if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT)
        wprintf(L"  WSA_FLAG_MULTIPOINT_C_ROOT");
    if (dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF)
        wprintf(L"  WSA_FLAG_MULTIPOINT_C_LEAF");
    if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT)
        wprintf(L"  WSA_FLAG_MULTIPOINT_D_ROOT");
    if (dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF)
        wprintf(L"  WSA_FLAG_MULTIPOINT_D_LEAF");
    if (dwFlags & WSA_FLAG_ACCESS_SYSTEM_SECURITY)
        wprintf(L"  WSA_FLAG_ACCESS_SYSTEM_SECURITY");
#ifdef WSA_FLAG_NO_HANDLE_INHERIT 
    if (dwFlags & WSA_FLAG_NO_HANDLE_INHERIT)
        wprintf(L"  WSA_FLAG_NO_HANDLE_INHERIT");
#endif
    wprintf(L" (0x%x)\n" , dwFlags);

    sock = WSASocket(iFamily, iType, iProtocol, NULL, 0, dwFlags);
    if (sock == INVALID_SOCKET) 
        wprintf(L"WSASocket function failed with error = %d\n", WSAGetLastError() );
    else {
        wprintf(L"WSASocket function succeeded\n");

        // Close the socket to release the resources associated
        // Normally an application calls shutdown() before closesocket 
        //   to  disables sends or receives on a socket first
        // This isn't needed in this simple sample
        iResult = closesocket(sock);
        if (iResult == SOCKET_ERROR) {
            wprintf(L"closesocket function zfailed with error = %d\n", WSAGetLastError() );
            WSACleanup();
            return 1;
        }    
    }
    WSACleanup();

    return 0;
}

Windows Phone 8: WSASocketW 関数は、Windows Phone 8 以降の Windows Phone Store アプリでサポートされます。

Windows 8.1 および Windows Server 2012 R2: WSASocketW 関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows Store アプリでサポートされます。

メモ

winsock2.h ヘッダーは WSASocket を、UNICODE プリプロセッサ定数の定義に基づいてこの関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして定義します。エンコーディング中立なエイリアスの使用と、エンコーディング中立でないコードとを混在させると、コンパイルエラーやランタイムエラーを引き起こす不一致につながる可能性があります。詳細については、Conventions for Function Prototypes を参照してください。

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

各言語での呼び出し定義

// WS2_32.dll  (ANSI / -A)
#include <windows.h>

SOCKET WSASocketA(
    INT af,
    INT type,
    INT protocol,
    WSAPROTOCOL_INFOA* lpProtocolInfo,   // optional
    DWORD g,
    DWORD dwFlags
);
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static extern UIntPtr WSASocketA(
    int af,   // INT
    int type,   // INT
    int protocol,   // INT
    IntPtr lpProtocolInfo,   // WSAPROTOCOL_INFOA* optional
    uint g,   // DWORD
    uint dwFlags   // DWORD
);
<DllImport("WS2_32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSASocketA(
    af As Integer,   ' INT
    type As Integer,   ' INT
    protocol As Integer,   ' INT
    lpProtocolInfo As IntPtr,   ' WSAPROTOCOL_INFOA* optional
    g As UInteger,   ' DWORD
    dwFlags As UInteger   ' DWORD
) As UIntPtr
End Function
' af : INT
' type : INT
' protocol : INT
' lpProtocolInfo : WSAPROTOCOL_INFOA* optional
' g : DWORD
' dwFlags : DWORD
Declare PtrSafe Function WSASocketA Lib "ws2_32" ( _
    ByVal af As Long, _
    ByVal type As Long, _
    ByVal protocol As Long, _
    ByVal lpProtocolInfo As LongPtr, _
    ByVal g As Long, _
    ByVal dwFlags As Long) As LongPtr
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WSASocketA = ctypes.windll.ws2_32.WSASocketA
WSASocketA.restype = ctypes.c_size_t
WSASocketA.argtypes = [
    ctypes.c_int,  # af : INT
    ctypes.c_int,  # type : INT
    ctypes.c_int,  # protocol : INT
    ctypes.c_void_p,  # lpProtocolInfo : WSAPROTOCOL_INFOA* optional
    wintypes.DWORD,  # g : DWORD
    wintypes.DWORD,  # dwFlags : DWORD
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WS2_32.dll')
WSASocketA = Fiddle::Function.new(
  lib['WSASocketA'],
  [
    Fiddle::TYPE_INT,  # af : INT
    Fiddle::TYPE_INT,  # type : INT
    Fiddle::TYPE_INT,  # protocol : INT
    Fiddle::TYPE_VOIDP,  # lpProtocolInfo : WSAPROTOCOL_INFOA* optional
    -Fiddle::TYPE_INT,  # g : DWORD
    -Fiddle::TYPE_INT,  # dwFlags : DWORD
  ],
  Fiddle::TYPE_UINTPTR_T)
#[link(name = "ws2_32")]
extern "system" {
    fn WSASocketA(
        af: i32,  // INT
        type: i32,  // INT
        protocol: i32,  // INT
        lpProtocolInfo: *mut WSAPROTOCOL_INFOA,  // WSAPROTOCOL_INFOA* optional
        g: u32,  // DWORD
        dwFlags: u32  // DWORD
    ) -> usize;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern UIntPtr WSASocketA(int af, int type, int protocol, IntPtr lpProtocolInfo, uint g, uint dwFlags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSASocketA' -Namespace Win32 -PassThru
# $api::WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags)
#uselib "WS2_32.dll"
#func global WSASocketA "WSASocketA" sptr, sptr, sptr, sptr, sptr, sptr
; WSASocketA af, type, protocol, varptr(lpProtocolInfo), g, dwFlags   ; 戻り値は stat
; af : INT -> "sptr"
; type : INT -> "sptr"
; protocol : INT -> "sptr"
; lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> "sptr"
; g : DWORD -> "sptr"
; dwFlags : DWORD -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WS2_32.dll"
#cfunc global WSASocketA "WSASocketA" int, int, int, var, int, int
; res = WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags)
; af : INT -> "int"
; type : INT -> "int"
; protocol : INT -> "int"
; lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> "var"
; g : DWORD -> "int"
; dwFlags : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; SOCKET WSASocketA(INT af, INT type, INT protocol, WSAPROTOCOL_INFOA* lpProtocolInfo, DWORD g, DWORD dwFlags)
#uselib "WS2_32.dll"
#cfunc global WSASocketA "WSASocketA" int, int, int, var, int, int
; res = WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags)
; af : INT -> "int"
; type : INT -> "int"
; protocol : INT -> "int"
; lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> "var"
; g : DWORD -> "int"
; dwFlags : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procWSASocketA = ws2_32.NewProc("WSASocketA")
)

// af (INT), type (INT), protocol (INT), lpProtocolInfo (WSAPROTOCOL_INFOA* optional), g (DWORD), dwFlags (DWORD)
r1, _, err := procWSASocketA.Call(
	uintptr(af),
	uintptr(type),
	uintptr(protocol),
	uintptr(lpProtocolInfo),
	uintptr(g),
	uintptr(dwFlags),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // SOCKET
function WSASocketA(
  af: Integer;   // INT
  type: Integer;   // INT
  protocol: Integer;   // INT
  lpProtocolInfo: Pointer;   // WSAPROTOCOL_INFOA* optional
  g: DWORD;   // DWORD
  dwFlags: DWORD   // DWORD
): NativeUInt; stdcall;
  external 'WS2_32.dll' name 'WSASocketA';
result := DllCall("WS2_32\WSASocketA"
    , "Int", af   ; INT
    , "Int", type   ; INT
    , "Int", protocol   ; INT
    , "Ptr", lpProtocolInfo   ; WSAPROTOCOL_INFOA* optional
    , "UInt", g   ; DWORD
    , "UInt", dwFlags   ; DWORD
    , "UPtr")   ; return: SOCKET
●WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags) = DLL("WS2_32.dll", "int WSASocketA(int, int, int, void*, dword, dword)")
# 呼び出し: WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags)
# af : INT -> "int"
# type : INT -> "int"
# protocol : INT -> "int"
# lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> "void*"
# g : DWORD -> "dword"
# dwFlags : DWORD -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "ws2_32" fn WSASocketA(
    af: i32, // INT
    type: i32, // INT
    protocol: i32, // INT
    lpProtocolInfo: [*c]WSAPROTOCOL_INFOA, // WSAPROTOCOL_INFOA* optional
    g: u32, // DWORD
    dwFlags: u32 // DWORD
) callconv(std.os.windows.WINAPI) usize;
proc WSASocketA(
    af: int32,  # INT
    `type`: int32,  # INT
    protocol: int32,  # INT
    lpProtocolInfo: ptr WSAPROTOCOL_INFOA,  # WSAPROTOCOL_INFOA* optional
    g: uint32,  # DWORD
    dwFlags: uint32  # DWORD
): uint {.importc: "WSASocketA", stdcall, dynlib: "WS2_32.dll".}
pragma(lib, "ws2_32");
extern(Windows)
size_t WSASocketA(
    int af,   // INT
    int type,   // INT
    int protocol,   // INT
    WSAPROTOCOL_INFOA* lpProtocolInfo,   // WSAPROTOCOL_INFOA* optional
    uint g,   // DWORD
    uint dwFlags   // DWORD
);
ccall((:WSASocketA, "WS2_32.dll"), stdcall, Csize_t,
      (Int32, Int32, Int32, Ptr{WSAPROTOCOL_INFOA}, UInt32, UInt32),
      af, type, protocol, lpProtocolInfo, g, dwFlags)
# af : INT -> Int32
# type : INT -> Int32
# protocol : INT -> Int32
# lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> Ptr{WSAPROTOCOL_INFOA}
# g : DWORD -> UInt32
# dwFlags : DWORD -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
uintptr_t WSASocketA(
    int32_t af,
    int32_t type,
    int32_t protocol,
    void* lpProtocolInfo,
    uint32_t g,
    uint32_t dwFlags);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags)
-- af : INT
-- type : INT
-- protocol : INT
-- lpProtocolInfo : WSAPROTOCOL_INFOA* optional
-- g : DWORD
-- dwFlags : DWORD
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSASocketA = lib.func('__stdcall', 'WSASocketA', 'uintptr_t', ['int32_t', 'int32_t', 'int32_t', 'void *', 'uint32_t', 'uint32_t']);
// WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags)
// af : INT -> 'int32_t'
// type : INT -> 'int32_t'
// protocol : INT -> 'int32_t'
// lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> 'void *'
// g : DWORD -> 'uint32_t'
// dwFlags : DWORD -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("WS2_32.dll", {
  WSASocketA: { parameters: ["i32", "i32", "i32", "pointer", "u32", "u32"], result: "usize" },
});
// lib.symbols.WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags)
// af : INT -> "i32"
// type : INT -> "i32"
// protocol : INT -> "i32"
// lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> "pointer"
// g : DWORD -> "u32"
// dwFlags : DWORD -> "u32"
// 文字列は "buffer"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
size_t WSASocketA(
    int32_t af,
    int32_t type,
    int32_t protocol,
    void* lpProtocolInfo,
    uint32_t g,
    uint32_t dwFlags);
C, "WS2_32.dll");
// $ffi->WSASocketA(af, type, protocol, lpProtocolInfo, g, dwFlags);
// af : INT
// type : INT
// protocol : INT
// lpProtocolInfo : WSAPROTOCOL_INFOA* optional
// g : DWORD
// dwFlags : DWORD
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Ws2_32 extends StdCallLibrary {
    Ws2_32 INSTANCE = Native.load("ws2_32", Ws2_32.class, W32APIOptions.ASCII_OPTIONS);
    long WSASocketA(
        int af,   // INT
        int type,   // INT
        int protocol,   // INT
        Pointer lpProtocolInfo,   // WSAPROTOCOL_INFOA* optional
        int g,   // DWORD
        int dwFlags   // DWORD
    );
}
@[Link("ws2_32")]
lib LibWS2_32
  fun WSASocketA = WSASocketA(
    af : Int32,   # INT
    type_ : Int32,   # INT
    protocol : Int32,   # INT
    lpProtocolInfo : WSAPROTOCOL_INFOA*,   # WSAPROTOCOL_INFOA* optional
    g : UInt32,   # DWORD
    dwFlags : UInt32   # DWORD
  ) : LibC::SizeT
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef WSASocketANative = UintPtr Function(Int32, Int32, Int32, Pointer<Void>, Uint32, Uint32);
typedef WSASocketADart = int Function(int, int, int, Pointer<Void>, int, int);
final WSASocketA = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<WSASocketANative, WSASocketADart>('WSASocketA');
// af : INT -> Int32
// type : INT -> Int32
// protocol : INT -> Int32
// lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> Pointer<Void>
// g : DWORD -> Uint32
// dwFlags : DWORD -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WSASocketA(
  af: Integer;   // INT
  type: Integer;   // INT
  protocol: Integer;   // INT
  lpProtocolInfo: Pointer;   // WSAPROTOCOL_INFOA* optional
  g: DWORD;   // DWORD
  dwFlags: DWORD   // DWORD
): NativeUInt; stdcall;
  external 'WS2_32.dll' name 'WSASocketA';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WSASocketA"
  c_WSASocketA :: Int32 -> Int32 -> Int32 -> Ptr () -> Word32 -> Word32 -> IO CUIntPtr
-- af : INT -> Int32
-- type : INT -> Int32
-- protocol : INT -> Int32
-- lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> Ptr ()
-- g : DWORD -> Word32
-- dwFlags : DWORD -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wsasocketa =
  foreign "WSASocketA"
    (int32_t @-> int32_t @-> int32_t @-> (ptr void) @-> uint32_t @-> uint32_t @-> returning size_t)
(* af : INT -> int32_t *)
(* type : INT -> int32_t *)
(* protocol : INT -> int32_t *)
(* lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> (ptr void) *)
(* g : DWORD -> uint32_t *)
(* dwFlags : DWORD -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library ws2_32 (t "WS2_32.dll"))
(cffi:use-foreign-library ws2_32)

(cffi:defcfun ("WSASocketA" wsasocket-a :convention :stdcall) :uint64
  (af :int32)   ; INT
  (type :int32)   ; INT
  (protocol :int32)   ; INT
  (lp-protocol-info :pointer)   ; WSAPROTOCOL_INFOA* optional
  (g :uint32)   ; DWORD
  (dw-flags :uint32))   ; DWORD
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WSASocketA = Win32::API::More->new('WS2_32',
    'WPARAM WSASocketA(int af, int type, int protocol, LPVOID lpProtocolInfo, DWORD g, DWORD dwFlags)');
# my $ret = $WSASocketA->Call($af, $type, $protocol, $lpProtocolInfo, $g, $dwFlags);
# af : INT -> int
# type : INT -> int
# protocol : INT -> int
# lpProtocolInfo : WSAPROTOCOL_INFOA* optional -> LPVOID
# g : DWORD -> DWORD
# dwFlags : DWORD -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

文字セット違い
公式の関連項目
使用する型