WSASocketW
関数シグネチャ
// WS2_32.dll (Unicode / -W)
#include <windows.h>
SOCKET WSASocketW(
INT af,
INT type,
INT protocol,
WSAPROTOCOL_INFOW* lpProtocolInfo, // optional
DWORD g,
DWORD dwFlags
);パラメーター
| 名前 | 型 | 方向 | 説明 | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| af | INT | in | アドレスファミリの指定。アドレスファミリに指定できる値は 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_INET と PF_INET)、どちらの定数も使用できます。 以下の表は、アドレスファミリの一般的な値を示しています。ただし、他にも多くの値が使用可能です。
| ||||||||||||||||||
| type | INT | in | 新しいソケットの種類の指定。 ソケットの種類に指定できる値は Winsock2.h ヘッダーファイルで定義されています。 以下の表は、Windows Sockets 2 でサポートされる type パラメーターに指定可能な値を示しています。
Windows Sockets 2 では、新しいソケットの種類が導入されました。アプリケーションは、 WSAEnumProtocols 関数を通じて、利用可能な各トランスポートプロトコルの属性を動的に検出できます。したがって、アプリケーションはアドレスファミリに対して可能なソケットの種類とプロトコルオプションを判別し、その情報をこのパラメーターの指定に利用できます。Winsock2.h および Ws2def.h ヘッダーファイル内のソケットの種類の定義は、新しいソケットの種類、アドレスファミリ、プロトコルが定義されるにつれて定期的に更新されます。 Windows Sockets 1.1 では、使用可能なソケットの種類は SOCK_DGRAM と SOCK_STREAM のみです。 | ||||||||||||||||||
| protocol | INT | in | 使用するプロトコル。protocol パラメーターに指定可能なオプションは、指定されたアドレスファミリとソケットの種類に固有です。protocol に指定可能な値は Winsock2.h および Wsrm.h ヘッダーファイルで定義されています。 Windows Vista 以降向けにリリースされた Windows SDK では、ヘッダーファイルの構成が変更され、このパラメーターには Ws2def.h ヘッダーファイルで定義された IPPROTO 列挙型の値のいずれかを指定できます。なお、Ws2def.h ヘッダーファイルは Winsock2.h に自動的にインクルードされるため、直接使用してはいけません。 値 0 を指定した場合、呼び出し元はプロトコルを指定しないことを意味し、サービスプロバイダーが使用する protocol を選択します。 af パラメーターが AF_INET または AF_INET6 で、type が SOCK_RAW の場合、protocol に指定された値は IPv6 または IPv4 パケットヘッダーのプロトコルフィールドに設定されます。 以下の表は、protocol の一般的な値を示しています。ただし、他にも多くの値が使用可能です。
| ||||||||||||||||||
| lpProtocolInfo | WSAPROTOCOL_INFOW* | inoptional | 作成するソケットの特性を定義する WSAPROTOCOL_INFO 構造体へのポインター。このパラメーターが NULL でない場合、ソケットは指定された WSAPROTOCOL_INFO 構造体に関連付けられたプロバイダーにバインドされます。 | ||||||||||||||||||
| g | DWORD | in | 既存のソケットグループ ID、または新しいソケットと新しいソケットグループを作成する際に取るべき適切なアクション。 g が既存のソケットグループ ID の場合、このグループが設定するすべての要件が満たされていれば、新しいソケットをこのソケットグループに参加させます。 g が既存のソケットグループ ID でない場合、以下の値が指定可能です。
注意 SG_UNCONSTRAINED_GROUP および SG_CONSTRAINED_GROUP 定数は、現在パブリックなヘッダーファイルでは定義されていません。
| ||||||||||||||||||
| dwFlags | DWORD | in | 追加のソケット属性を指定するために使用するフラグのセット。 これらのフラグの組み合わせを設定できますが、一部の組み合わせは許可されません。
重要 マルチポイントソケットでは、WSA_FLAG_MULTIPOINT_C_ROOT または WSA_FLAG_MULTIPOINT_C_LEAF フラグのいずれか一方のみを指定でき、また WSA_FLAG_MULTIPOINT_D_ROOT または WSA_FLAG_MULTIPOINT_D_LEAF フラグのいずれか一方のみを指定できます。追加情報については
Multipoint and Multicast Semantics を参照してください。
|
戻り値の型: SOCKET
公式ドキュメント
WSASocket 関数は、特定のトランスポートサービスプロバイダーにバインドされたソケットを作成します。(Unicode)
戻り値
エラーが発生しなかった場合、 WSASocket は新しいソケットを参照する記述子を返します。それ以外の場合は INVALID_SOCKET の値が返され、 WSAGetLastError を呼び出すことで特定のエラーコードを取得できます。
| エラーコード | 意味 |
|---|---|
| この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。 | |
| ネットワークサブシステムに障害が発生しました。 | |
| 指定されたアドレスファミリはサポートされていません。 | |
| lpProtocolInfo パラメーターがプロセスアドレス空間の有効な部分にありません。 | |
| ブロッキング型の Windows Sockets 1.1 呼び出しが進行中であるか、サービスプロバイダーがコールバック関数をまだ処理中です。 | |
この値は、以下のいずれかの条件に該当する場合に発生します。
|
|
| サービスプロバイダーが 2.2 以外のバージョンを返しました。 | |
| サービスプロバイダーが WSPStartup に無効または不完全なプロシージャテーブルを返しました。 | |
| 使用可能なソケット記述子がこれ以上ありません。 | |
| 使用可能なバッファー領域がありません。ソケットを作成できません。 | |
| 指定されたプロトコルはサポートされていません。 | |
| 指定されたプロトコルは、このソケットには不適切な種類です。 | |
| サービスプロバイダーの初期化に失敗しました。このエラーは、レイヤードサービスプロバイダー (LSP) または名前空間プロバイダーが正しくインストールされていない場合、あるいはプロバイダーが正しく動作しない場合に返されます。 | |
| 指定されたソケットの種類は、このアドレスファミリではサポートされていません。 |
解説(Remarks)
WSASocket 関数は、ソケット記述子および関連するリソースを割り当て、トランスポートサービスプロバイダーに関連付けます。ほとんどのソケットは、dwFlags パラメーターに WSA_FLAG_OVERLAPPED 属性を設定して作成すべきです。この属性を設定して作成されたソケットは、より高いパフォーマンスを提供するオーバーラップ I/O 操作の使用をサポートします。既定では、WSASocket 関数で作成されたソケットにはこのオーバーラップ属性は設定されません。これに対して、socket 関数は、既定の動作としてオーバーラップ I/O 操作をサポートするソケットを作成します。
lpProtocolInfo パラメーターが NULL の場合、Winsock は、af、type、protocol パラメーターで指定された、要求されたアドレスファミリ、ソケットの種類、プロトコルの組み合わせをサポートする最初に利用可能なトランスポートサービスプロバイダーを利用します。
lpProtocolInfo パラメーターが NULL でない場合、ソケットは指定された WSAPROTOCOL_INFO 構造体に関連付けられたプロバイダーにバインドされます。この場合、アプリケーションは af、type、protocol パラメーターのいずれの値としてもマニフェスト定数 FROM_PROTOCOL_INFO を指定できます。これは、指定された WSAPROTOCOL_INFO 構造体の対応する値(iAddressFamily、iSocketType、iProtocol)が想定されることを示します。いずれの場合も、af、type、protocol に指定された値は変更されることなくトランスポートサービスプロバイダーに渡されます。
af、type、protocol に基づいてプロトコルとそれをサポートするサービスプロバイダーを選択する際、この手続きはベースプロトコルまたはプロトコルチェーンのみを選択し、プロトコルレイヤー単独は選択しません。チェーン化されていないプロトコルレイヤーは、type または af の部分一致を持つとも見なされません。つまり、適切なプロトコルが見つからなかった場合でも、それらは WSAEAFNOSUPPORT や WSAEPROTONOSUPPORT のエラーコードにはつながりません。
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 関数は、サービスで使用するソケットを作成するために使用できます。これにより、別のソケットがそのサービスで使用されているのと同じポートにバインドしようとした場合に、監査レコードが生成されます。このオプションを有効にするには、アプリケーションは次の操作を行う必要があります。
- AdjustTokenPrivileges 関数を呼び出して、プロセスのアクセストークンで SE_SECURITY_NAME 特権を有効にします。この特権は、オブジェクトのセキュリティ記述子に ACCESS_SYSTEM_SECURITY アクセス権を設定するために必要です。
- WSASocket 関数を呼び出し、dwFlag に WSA_FLAG_ACCESS_SYSTEM_SECURITY オプションを設定してソケットを作成します。この操作に必要な SE_SECURITY_NAME 特権を有効にするために、先に AdjustTokenPrivileges 関数が呼び出されていない場合、WSASocket 関数は失敗します。
- SetSecurityInfo 関数を呼び出して、System Access Control List (SACL) を含むセキュリティ記述子をソケットに設定します。WSASocket 関数によって返されたソケットハンドルが handle パラメーターに渡されます。関数が成功すると、ソケットのセキュリティ記述子に ACCESS_SYSTEM_SECURITY アクセス権が設定されます。
- bind 関数を呼び出して、ソケットを特定のポートにバインドします。bind 関数が成功すると、別のソケットが同じポートにバインドしようとした場合に監査エントリが生成されます。
- AdjustTokenPrivileges 関数を呼び出して、不要になったプロセスのアクセストークンの SE_SECURITY_NAME 特権を削除します。
ACCESS_SYSTEM_SECURITY の詳細については、Authorization ドキュメントの SACL Access Right および Audit Generation を参照してください。
ソケットグループ
WinSock 2 では、アプリケーション、または連携するアプリケーションのセットが、特定のソケットのセットが関連していること、およびそうして形成されたグループが特定の属性を持つことを、基盤となるサービスプロバイダーに示す手段として、ソケットグループという概念が導入されました。グループ属性には、グループ内の個々のソケットの相対的な優先順位と、グループのサービス品質仕様が含まれます。ネットワーク上でマルチメディアストリームを交換する必要があるアプリケーションは、ソケットのセット間に特定の関係を確立できることが有益となる例です。ソケットグループをどのように扱うかはトランスポート次第です。
WSASocket および WSAAccept 関数を使用して、新しいソケットを作成する際にソケットグループを明示的に作成して参加させることができます。ソケットのソケットグループ ID は、getsockopt 関数で level パラメーターを SOL_SOCKET に、optname パラメーターを SO_GROUP_ID に設定することで取得できます。ソケットグループとそれに関連付けられたソケットグループ ID は、このソケットグループに属する最後のソケットが閉じられるまで有効なままです。ソケットグループ ID は、特定のサービスプロバイダーに対するすべてのプロセスにわたって一意です。ソケットグループが 0 の場合、そのソケットがソケットグループのメンバーでないことを示します。
ソケットグループの相対的なグループ優先順位には、getsockopt 関数で level パラメーターを SOL_SOCKET に、optname パラメーターを SO_GROUP_PRIORITY に設定することでアクセスできます。ソケットグループの相対的なグループ優先順位は、setsockopt で level パラメーターを SOL_SOCKET に、optname パラメーターを SO_GROUP_PRIORITY に設定することで設定できます。
Windows に含まれる Winsock プロバイダーは、ソケットグループの作成を許可し、SG_CONSTRAINED_GROUP を強制します。制約のあるソケットグループ内のすべてのソケットは、type および protocol パラメーターに同じ値で作成される必要があります。制約のあるソケットグループはコネクション指向のソケットのみで構成でき、グループ化されたすべてのソケットの接続が同じホスト上の同じアドレスへの接続であることを必要とします。これが、Windows に含まれる Winsock プロバイダーがソケットグループに適用する唯一の制限です。ソケットグループの優先順位は、Windows に含まれる Winsock プロバイダーや TCP/IP スタックでは現在使用されていません。
コード例
以下の例は、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 ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして WSASocket を定義しています。エンコーディング中立のエイリアスの使用を、エンコーディング中立でないコードと混在させると、コンパイルエラーや実行時エラーを引き起こす不一致につながる可能性があります。詳細については、Conventions for Function Prototypes を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// WS2_32.dll (Unicode / -W)
#include <windows.h>
SOCKET WSASocketW(
INT af,
INT type,
INT protocol,
WSAPROTOCOL_INFOW* lpProtocolInfo, // optional
DWORD g,
DWORD dwFlags
);[DllImport("WS2_32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
static extern UIntPtr WSASocketW(
int af, // INT
int type, // INT
int protocol, // INT
IntPtr lpProtocolInfo, // WSAPROTOCOL_INFOW* optional
uint g, // DWORD
uint dwFlags // DWORD
);<DllImport("WS2_32.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSASocketW(
af As Integer, ' INT
type As Integer, ' INT
protocol As Integer, ' INT
lpProtocolInfo As IntPtr, ' WSAPROTOCOL_INFOW* optional
g As UInteger, ' DWORD
dwFlags As UInteger ' DWORD
) As UIntPtr
End Function' af : INT
' type : INT
' protocol : INT
' lpProtocolInfo : WSAPROTOCOL_INFOW* optional
' g : DWORD
' dwFlags : DWORD
Declare PtrSafe Function WSASocketW 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
' Unicode(W): 文字列は ByVal As LongPtr とし StrPtr(unicodeStr) を渡す
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
WSASocketW = ctypes.windll.ws2_32.WSASocketW
WSASocketW.restype = ctypes.c_size_t
WSASocketW.argtypes = [
ctypes.c_int, # af : INT
ctypes.c_int, # type : INT
ctypes.c_int, # protocol : INT
ctypes.c_void_p, # lpProtocolInfo : WSAPROTOCOL_INFOW* 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')
WSASocketW = Fiddle::Function.new(
lib['WSASocketW'],
[
Fiddle::TYPE_INT, # af : INT
Fiddle::TYPE_INT, # type : INT
Fiddle::TYPE_INT, # protocol : INT
Fiddle::TYPE_VOIDP, # lpProtocolInfo : WSAPROTOCOL_INFOW* optional
-Fiddle::TYPE_INT, # g : DWORD
-Fiddle::TYPE_INT, # dwFlags : DWORD
],
Fiddle::TYPE_UINTPTR_T)
# Wide strings: pass str.encode("UTF-16LE") + "\x00\x00"#[link(name = "ws2_32")]
extern "system" {
fn WSASocketW(
af: i32, // INT
type: i32, // INT
protocol: i32, // INT
lpProtocolInfo: *mut WSAPROTOCOL_INFOW, // WSAPROTOCOL_INFOW* 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.Unicode, SetLastError = true)]
public static extern UIntPtr WSASocketW(int af, int type, int protocol, IntPtr lpProtocolInfo, uint g, uint dwFlags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSASocketW' -Namespace Win32 -PassThru
# $api::WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)#uselib "WS2_32.dll"
#func global WSASocketW "WSASocketW" wptr, wptr, wptr, wptr, wptr, wptr
; WSASocketW af, type, protocol, varptr(lpProtocolInfo), g, dwFlags ; 戻り値は stat
; af : INT -> "wptr"
; type : INT -> "wptr"
; protocol : INT -> "wptr"
; lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "wptr"
; g : DWORD -> "wptr"
; dwFlags : DWORD -> "wptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "WS2_32.dll" #cfunc global WSASocketW "WSASocketW" int, int, int, var, int, int ; res = WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags) ; af : INT -> "int" ; type : INT -> "int" ; protocol : INT -> "int" ; lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "var" ; g : DWORD -> "int" ; dwFlags : DWORD -> "int" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "WS2_32.dll" #cfunc global WSASocketW "WSASocketW" int, int, int, sptr, int, int ; res = WSASocketW(af, type, protocol, varptr(lpProtocolInfo), g, dwFlags) ; af : INT -> "int" ; type : INT -> "int" ; protocol : INT -> "int" ; lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "sptr" ; g : DWORD -> "int" ; dwFlags : DWORD -> "int" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; SOCKET WSASocketW(INT af, INT type, INT protocol, WSAPROTOCOL_INFOW* lpProtocolInfo, DWORD g, DWORD dwFlags) #uselib "WS2_32.dll" #cfunc global WSASocketW "WSASocketW" int, int, int, var, int, int ; res = WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags) ; af : INT -> "int" ; type : INT -> "int" ; protocol : INT -> "int" ; lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "var" ; g : DWORD -> "int" ; dwFlags : DWORD -> "int" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; SOCKET WSASocketW(INT af, INT type, INT protocol, WSAPROTOCOL_INFOW* lpProtocolInfo, DWORD g, DWORD dwFlags) #uselib "WS2_32.dll" #cfunc global WSASocketW "WSASocketW" int, int, int, intptr, int, int ; res = WSASocketW(af, type, protocol, varptr(lpProtocolInfo), g, dwFlags) ; af : INT -> "int" ; type : INT -> "int" ; protocol : INT -> "int" ; lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "intptr" ; g : DWORD -> "int" ; dwFlags : DWORD -> "int" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
procWSASocketW = ws2_32.NewProc("WSASocketW")
)
// af (INT), type (INT), protocol (INT), lpProtocolInfo (WSAPROTOCOL_INFOW* optional), g (DWORD), dwFlags (DWORD)
r1, _, err := procWSASocketW.Call(
uintptr(af),
uintptr(type),
uintptr(protocol),
uintptr(lpProtocolInfo),
uintptr(g),
uintptr(dwFlags),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // SOCKETfunction WSASocketW(
af: Integer; // INT
type: Integer; // INT
protocol: Integer; // INT
lpProtocolInfo: Pointer; // WSAPROTOCOL_INFOW* optional
g: DWORD; // DWORD
dwFlags: DWORD // DWORD
): NativeUInt; stdcall;
external 'WS2_32.dll' name 'WSASocketW';result := DllCall("WS2_32\WSASocketW"
, "Int", af ; INT
, "Int", type ; INT
, "Int", protocol ; INT
, "Ptr", lpProtocolInfo ; WSAPROTOCOL_INFOW* optional
, "UInt", g ; DWORD
, "UInt", dwFlags ; DWORD
, "UPtr") ; return: SOCKET●WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags) = DLL("WS2_32.dll", "int WSASocketW(int, int, int, void*, dword, dword)")
# 呼び出し: WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
# af : INT -> "int"
# type : INT -> "int"
# protocol : INT -> "int"
# lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "void*"
# g : DWORD -> "dword"
# dwFlags : DWORD -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
# ※-W(Unicode)関数。なでしこ1はANSIのため -A 版の利用を推奨。const std = @import("std");
extern "ws2_32" fn WSASocketW(
af: i32, // INT
type: i32, // INT
protocol: i32, // INT
lpProtocolInfo: [*c]WSAPROTOCOL_INFOW, // WSAPROTOCOL_INFOW* optional
g: u32, // DWORD
dwFlags: u32 // DWORD
) callconv(std.os.windows.WINAPI) usize;
// Unicode(-W): UTF-16LE のヌル終端バッファ([*c]const u16)を渡す。proc WSASocketW(
af: int32, # INT
`type`: int32, # INT
protocol: int32, # INT
lpProtocolInfo: ptr WSAPROTOCOL_INFOW, # WSAPROTOCOL_INFOW* optional
g: uint32, # DWORD
dwFlags: uint32 # DWORD
): uint {.importc: "WSASocketW", stdcall, dynlib: "WS2_32.dll".}
# Unicode(-W): WideCString は newWideCString("...") で生成。pragma(lib, "ws2_32");
extern(Windows)
size_t WSASocketW(
int af, // INT
int type, // INT
int protocol, // INT
WSAPROTOCOL_INFOW* lpProtocolInfo, // WSAPROTOCOL_INFOW* optional
uint g, // DWORD
uint dwFlags // DWORD
);ccall((:WSASocketW, "WS2_32.dll"), stdcall, Csize_t,
(Int32, Int32, Int32, Ptr{WSAPROTOCOL_INFOW}, UInt32, UInt32),
af, type, protocol, lpProtocolInfo, g, dwFlags)
# af : INT -> Int32
# type : INT -> Int32
# protocol : INT -> Int32
# lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> Ptr{WSAPROTOCOL_INFOW}
# g : DWORD -> UInt32
# dwFlags : DWORD -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
# Unicode(-W): Cwstring には transcode(UInt16, "...") 等で UTF-16 を渡す。local ffi = require("ffi")
ffi.cdef[[
uintptr_t WSASocketW(
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.WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
-- af : INT
-- type : INT
-- protocol : INT
-- lpProtocolInfo : WSAPROTOCOL_INFOW* optional
-- g : DWORD
-- dwFlags : DWORD
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
-- Unicode(-W): uint16_t* には UTF-16LE のバッファ(ffi.new("uint16_t[?]", ...))を渡す。const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSASocketW = lib.func('__stdcall', 'WSASocketW', 'uintptr_t', ['int32_t', 'int32_t', 'int32_t', 'void *', 'uint32_t', 'uint32_t']);
// WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
// af : INT -> 'int32_t'
// type : INT -> 'int32_t'
// protocol : INT -> 'int32_t'
// lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> 'void *'
// g : DWORD -> 'uint32_t'
// dwFlags : DWORD -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("WS2_32.dll", {
WSASocketW: { parameters: ["i32", "i32", "i32", "pointer", "u32", "u32"], result: "usize" },
});
// lib.symbols.WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags)
// af : INT -> "i32"
// type : INT -> "i32"
// protocol : INT -> "i32"
// lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> "pointer"
// g : DWORD -> "u32"
// dwFlags : DWORD -> "u32"
// 文字列は "buffer"。Unicode(-W) は new TextEncoder() ではなく UTF-16LE のバイト列(末尾に \x00\x00)を Uint8Array で渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
size_t WSASocketW(
int32_t af,
int32_t type,
int32_t protocol,
void* lpProtocolInfo,
uint32_t g,
uint32_t dwFlags);
C, "WS2_32.dll");
// $ffi->WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags);
// af : INT
// type : INT
// protocol : INT
// lpProtocolInfo : WSAPROTOCOL_INFOW* 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.UNICODE_OPTIONS);
long WSASocketW(
int af, // INT
int type, // INT
int protocol, // INT
Pointer lpProtocolInfo, // WSAPROTOCOL_INFOW* optional
int g, // DWORD
int dwFlags // DWORD
);
}
// Unicode(-W): WString(入力)/char[](出力)で UTF-16 をマーシャリング。@[Link("ws2_32")]
lib LibWS2_32
fun WSASocketW = WSASocketW(
af : Int32, # INT
type_ : Int32, # INT
protocol : Int32, # INT
lpProtocolInfo : WSAPROTOCOL_INFOW*, # WSAPROTOCOL_INFOW* 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 WSASocketWNative = UintPtr Function(Int32, Int32, Int32, Pointer<Void>, Uint32, Uint32);
typedef WSASocketWDart = int Function(int, int, int, Pointer<Void>, int, int);
final WSASocketW = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<WSASocketWNative, WSASocketWDart>('WSASocketW');
// af : INT -> Int32
// type : INT -> Int32
// protocol : INT -> Int32
// lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> Pointer<Void>
// g : DWORD -> Uint32
// dwFlags : DWORD -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function WSASocketW(
af: Integer; // INT
type: Integer; // INT
protocol: Integer; // INT
lpProtocolInfo: Pointer; // WSAPROTOCOL_INFOW* optional
g: DWORD; // DWORD
dwFlags: DWORD // DWORD
): NativeUInt; stdcall;
external 'WS2_32.dll' name 'WSASocketW';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "WSASocketW"
c_WSASocketW :: Int32 -> Int32 -> Int32 -> Ptr () -> Word32 -> Word32 -> IO CUIntPtr
-- af : INT -> Int32
-- type : INT -> Int32
-- protocol : INT -> Int32
-- lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> Ptr ()
-- g : DWORD -> Word32
-- dwFlags : DWORD -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let wsasocketw =
foreign "WSASocketW"
(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_INFOW* 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 ("WSASocketW" wsasocket-w :convention :stdcall) :uint64
(af :int32) ; INT
(type :int32) ; INT
(protocol :int32) ; INT
(lp-protocol-info :pointer) ; WSAPROTOCOL_INFOW* optional
(g :uint32) ; DWORD
(dw-flags :uint32)) ; DWORD
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $WSASocketW = Win32::API::More->new('WS2_32',
'WPARAM WSASocketW(int af, int type, int protocol, LPVOID lpProtocolInfo, DWORD g, DWORD dwFlags)');
# my $ret = $WSASocketW->Call($af, $type, $protocol, $lpProtocolInfo, $g, $dwFlags);
# af : INT -> int
# type : INT -> int
# protocol : INT -> int
# lpProtocolInfo : WSAPROTOCOL_INFOW* optional -> LPVOID
# g : DWORD -> DWORD
# dwFlags : DWORD -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# Unicode(-W): LPCWSTR/LPWSTR は Win32::API が UTF-16 変換を行う。関連項目
- f WSASocketA (ANSI版) — プロトコル情報やフラグを指定してソケットを作成する。
- f accept — 接続要求を受け入れ新しいソケットを生成する。
- f bind — ソケットにローカルアドレスを割り当てる。
- f closesocket — ソケットを閉じてリソースを解放する。
- f connect — 指定アドレスへのソケット接続を確立する。
- f getsockname — ソケットに割り当てられたローカルアドレスを取得する。
- f getsockopt — ソケットオプションの値を取得する。
- f ioctlsocket — ソケットの入出力モードを制御する。
- f listen — ソケットを接続待ち受け状態にする。
- f recv — 接続ソケットからデータを受信する。
- f recvfrom — ソケットからデータを受信し送信元アドレスを取得する。
- f select — 複数ソケットの入出力可否を監視する。
- f send — 接続ソケットへデータを送信する。