WSAStartup
関数シグネチャ
// WS2_32.dll
#include <windows.h>
INT WSAStartup(
WORD wVersionRequested,
WSADATA* lpWSAData
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| wVersionRequested | WORD | in | 要求するWinsock仕様の最高バージョン。下位バイトがメジャー、上位がマイナー。通常MAKEWORD(2,2)。 |
| lpWSAData | WSADATA* | out | Windows Sockets 実装の詳細を受け取る WSADATA データ構造体へのポインター。 |
戻り値の型: INT
公式ドキュメント
WSAStartup 関数 (winsock.h) は、プロセスによる Winsock DLL の使用を開始します。
戻り値
成功した場合、 WSAStartup 関数はゼロを返します。それ以外の場合は、以下に示すエラーコードのいずれかを返します。
WSAStartup 関数は、この関数の戻り値として拡張エラーコードを直接返します。WSAGetLastError 関数の呼び出しは不要であり、使用すべきではありません。
| エラーコード | 意味 |
|---|---|
| 基盤となるネットワークサブシステムがネットワーク通信の準備ができていません。 | |
| 要求された Windows Sockets サポートのバージョンは、この特定の Windows Sockets 実装では提供されていません。 | |
| ブロッキングの Windows Sockets 1.1 操作が進行中です。 | |
| Windows Sockets 実装でサポートされるタスク数の上限に達しました。 | |
| lpWSAData パラメーターが有効なポインターではありません。 |
解説(Remarks)
WSAStartup 関数は、アプリケーションまたは DLL が最初に呼び出す Windows Sockets 関数でなければなりません。この関数によって、アプリケーションまたは DLL は必要とする Windows Sockets のバージョンを指定し、特定の Windows Sockets 実装の詳細を取得できます。アプリケーションまたは DLL は、 WSAStartup の呼び出しに成功した後でのみ、以降の Windows Sockets 関数を発行できます。
さまざまな Windows Sockets 実装、および最新バージョンの Windows Sockets 仕様と機能的な差異を持つ可能性のあるアプリケーションをサポートするため、 WSAStartup ではネゴシエーションが行われます。 WSAStartup の呼び出し元は、wVersionRequested パラメーターに、アプリケーションがサポートする Windows Sockets 仕様の最上位バージョンを渡します。Winsock DLL は、応答として自身がサポートできる Windows Sockets 仕様の最上位バージョンを示します。また Winsock DLL は、呼び出し元が使用することを想定する Windows Sockets 仕様のバージョンも返します。
アプリケーションまたは DLL が WSAStartup 関数を呼び出すと、Winsock DLL は wVersionRequested パラメーターで渡された、アプリケーションが要求する Windows Sockets 仕様のバージョンを調べます。アプリケーションが要求したバージョンが、Winsock DLL がサポートする最下位バージョン以上であれば、呼び出しは成功し、Winsock DLL は lpWSAData パラメーターが指す WSADATA 構造体に詳細情報を返します。WSADATA 構造体の wHighVersion メンバーは、Winsock DLL がサポートする Windows Sockets 仕様の最上位バージョンを示します。WSADATA 構造体の wVersion メンバーは、Winsock DLL が呼び出し元に使用してほしい Windows Sockets 仕様のバージョンを示します。
WSADATA 構造体の wVersion メンバーが呼び出し元にとって受け入れられない場合、アプリケーションまたは DLL は WSACleanup を呼び出して Winsock DLL のリソースを解放し、Winsock アプリケーションの初期化を失敗させるべきです。このアプリケーションまたは DLL をサポートするには、プラットフォームにインストールする更新版の Winsock DLL を探す必要があります。
Windows Sockets 仕様の現在のバージョンはバージョン 2.2 です。現在の Winsock DLL である Ws2_32.dll は、以下のいずれかのバージョンの Windows Sockets 仕様を要求するアプリケーションをサポートします。
- 1.0
- 1.1
- 2.0
- 2.1
- 2.2
上位バージョンの Windows Sockets 仕様の新しい構文への完全なアクセスを得るには、アプリケーションはその上位バージョンをネゴシエートする必要があります。この場合、wVersionRequested パラメーターはバージョン 2.2 を要求するように設定する必要があります。また、適切なヘッダーファイルに対するコンパイル、新しいライブラリとのリンクなどの特別な対応を含め、アプリケーションはその上位バージョンの Windows Socket 仕様に完全に準拠する必要があります。Winsock 2 サポート用の Winsock2.h ヘッダー ファイルは、Microsoft Windows Software Development Kit (SDK) に含まれています。
Windows Sockets バージョン 2.2 は、Windows Server 2008、
Windows Vista、Windows Server 2003、
Windows XP、
Windows 2000、Windows NT 4.0 (Service Pack 4 (SP4) 以降)、
Windows Me、
Windows 98、および Windows 95 OSR2 でサポートされています。
Windows Sockets バージョン 2.2 は、Windows Socket 2 Update を適用した
Windows 95 でもサポートされています。これらのプラットフォーム上のアプリケーションでは、通常 wVersionRequested パラメーターを適切に設定して Winsock 2.2 を要求すべきです。
Windows 95 および Windows NT 3.51 以前のバージョンでは、Windows Sockets バージョン 1.1 がサポートされる Windows Sockets 仕様の最上位バージョンです。
Winsock DLL がサポートする下位バージョンの Windows Sockets 仕様を使用するように記述されたアプリケーションまたは DLL が、WSAStartup 関数を使用してその下位バージョンのネゴシエーションに成功することは、正当であり可能です。たとえば、Winsock 2.2 DLL を持つプラットフォーム上で、アプリケーションは WSAStartup 関数に渡す wVersionRequested パラメーターでバージョン 1.1 を要求できます。この場合、アプリケーションは要求したバージョンの範囲に収まる機能のみに依存すべきです。新しい Ioctl コード、既存関数の新しい動作、および新しい関数は使用すべきではありません。WSAStartup によって提供されるバージョンネゴシエーションは、主に Windows 95 や Windows NT 3.51 以前向けに開発された古い Winsock 1.1 アプリケーションを、後続バージョンの Windows でも同じ動作で実行できるようにするために使用されていました。Winsock 1.1 サポート用の Winsock.h ヘッダー ファイルは Windows SDK に含まれています。
WSAStartup 関数におけるこのネゴシエーションにより、Windows Sockets を使用するアプリケーションまたは DLL と、Winsock DLL の両方が、一定範囲の Windows Sockets バージョンをサポートできます。バージョン範囲に重なりがあれば、アプリケーションまたは DLL は Winsock DLL を使用できます。Windows Sockets 実装に関する詳細情報は、WSAStartup 関数によって返される WSADATA 構造体に格納されます。
次の表は、さまざまなアプリケーションと Winsock DLL のバージョンにおいて WSAStartup がどのように動作するかを示しています。
| 呼び出し元がサポートするバージョン | Winsock DLL がサポートするバージョン | 要求された wVersion | 返された wVersion | 返された wHighVersion | 最終結果 |
|---|---|---|---|---|---|
| 1.1 | 1.1 | 1.1 | 1.1 | 1.1 | 1.1 を使用 |
| 1.0 1.1 | 1.0 | 1.1 | 1.0 | 1.0 | 1.0 を使用 |
| 1.0 | 1.0 1.1 | 1.0 | 1.0 | 1.1 | 1.0 を使用 |
| 1.1 | 1.0 1.1 | 1.1 | 1.1 | 1.1 | 1.1 を使用 |
| 1.1 | 1.0 | 1.1 | 1.0 | 1.0 | アプリケーションが失敗 |
| 1.0 | 1.1 | 1.0 | — | — | WSAVERNOTSUPPORTED |
| 1.0 1.1 | 1.0 1.1 | 1.1 | 1.1 | 1.1 | 1.1 を使用 |
| 1.1 2.0 | 1.0 1.1 | 2.0 | 1.1 | 1.1 | 1.1 を使用 |
| 2.0 | 1.0 1.1 2.0 | 2.0 | 2.0 | 2.0 | 2.0 を使用 |
| 2.0 2.2 | 1.0 1.1 2.0 | 2.2 | 2.0 | 2.0 | 2.0 を使用 |
| 2.2 | 1.0 1.1 2.0 2.1 2.2 | 2.2 | 2.2 | 2.2 | 2.2 を使用 |
アプリケーションまたは DLL が WSAStartup の呼び出しに成功すると、必要に応じて他の Windows Sockets 呼び出しを行えます。Winsock DLL のサービスの使用を終えたら、アプリケーションは WSACleanup を呼び出し、アプリケーションが使用した内部の Winsock リソースを Winsock DLL が解放できるようにする必要があります。
アプリケーションは、 WSADATA 構造体の情報を複数回取得する必要がある場合、 WSAStartup を複数回呼び出すことができます。そのような各呼び出しでは、アプリケーションは Winsock DLL がサポートする任意のバージョン番号を指定できます。
WSAStartup 関数は通常、プロトコル固有のヘルパー DLL の読み込みを引き起こします。そのため、 WSAStartup 関数はアプリケーション DLL の DllMain 関数から呼び出すべきではありません。デッドロックを引き起こす可能性があります。詳細については、DLL Main Function を参照してください。
アプリケーションは、WSAStartup 関数を呼び出して成功するたびに、その回数だけ WSACleanup 関数を呼び出す必要があります。つまり、たとえばアプリケーションが WSAStartup を 3 回呼び出した場合、 WSACleanup を 3 回呼び出す必要があります。最初の 2 回の WSACleanup 呼び出しは内部カウンターをデクリメントするだけで何も行わず、そのタスクに対する最後の WSACleanup 呼び出しが、タスクに必要なすべてのリソース解放を行います。
Windows Phone 8: この関数は、Windows Phone 8 以降の Windows Phone Store アプリでサポートされています。
Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows Store アプリでサポートされています。
例
次のコードフラグメントは、Windows Sockets のバージョン 2.2 のみをサポートするアプリケーションが WSAStartup 呼び出しを行う方法を示しています。
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")
int __cdecl main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\n", err);
return 1;
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return 1;
}
else
printf("The Winsock 2.2 dll was found okay\n");
/* The Winsock DLL is acceptable. Proceed to use it. */
/* Add network programming using Winsock here */
/* then call WSACleanup when done using the Winsock dll */
WSACleanup();
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// WS2_32.dll
#include <windows.h>
INT WSAStartup(
WORD wVersionRequested,
WSADATA* lpWSAData
);[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int WSAStartup(
ushort wVersionRequested, // WORD
IntPtr lpWSAData // WSADATA* out
);<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSAStartup(
wVersionRequested As UShort, ' WORD
lpWSAData As IntPtr ' WSADATA* out
) As Integer
End Function' wVersionRequested : WORD
' lpWSAData : WSADATA* out
Declare PtrSafe Function WSAStartup Lib "ws2_32" ( _
ByVal wVersionRequested As Integer, _
ByVal lpWSAData As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
WSAStartup = ctypes.windll.ws2_32.WSAStartup
WSAStartup.restype = ctypes.c_int
WSAStartup.argtypes = [
ctypes.c_ushort, # wVersionRequested : WORD
ctypes.c_void_p, # lpWSAData : WSADATA* out
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('WS2_32.dll')
WSAStartup = Fiddle::Function.new(
lib['WSAStartup'],
[
-Fiddle::TYPE_SHORT, # wVersionRequested : WORD
Fiddle::TYPE_VOIDP, # lpWSAData : WSADATA* out
],
Fiddle::TYPE_INT)#[link(name = "ws2_32")]
extern "system" {
fn WSAStartup(
wVersionRequested: u16, // WORD
lpWSAData: *mut WSADATA // WSADATA* out
) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern int WSAStartup(ushort wVersionRequested, IntPtr lpWSAData);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSAStartup' -Namespace Win32 -PassThru
# $api::WSAStartup(wVersionRequested, lpWSAData)#uselib "WS2_32.dll"
#func global WSAStartup "WSAStartup" sptr, sptr
; WSAStartup wVersionRequested, varptr(lpWSAData) ; 戻り値は stat
; wVersionRequested : WORD -> "sptr"
; lpWSAData : WSADATA* out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "WS2_32.dll" #cfunc global WSAStartup "WSAStartup" int, var ; res = WSAStartup(wVersionRequested, lpWSAData) ; wVersionRequested : WORD -> "int" ; lpWSAData : WSADATA* out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "WS2_32.dll" #cfunc global WSAStartup "WSAStartup" int, sptr ; res = WSAStartup(wVersionRequested, varptr(lpWSAData)) ; wVersionRequested : WORD -> "int" ; lpWSAData : WSADATA* out -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; INT WSAStartup(WORD wVersionRequested, WSADATA* lpWSAData) #uselib "WS2_32.dll" #cfunc global WSAStartup "WSAStartup" int, var ; res = WSAStartup(wVersionRequested, lpWSAData) ; wVersionRequested : WORD -> "int" ; lpWSAData : WSADATA* out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; INT WSAStartup(WORD wVersionRequested, WSADATA* lpWSAData) #uselib "WS2_32.dll" #cfunc global WSAStartup "WSAStartup" int, intptr ; res = WSAStartup(wVersionRequested, varptr(lpWSAData)) ; wVersionRequested : WORD -> "int" ; lpWSAData : WSADATA* out -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
procWSAStartup = ws2_32.NewProc("WSAStartup")
)
// wVersionRequested (WORD), lpWSAData (WSADATA* out)
r1, _, err := procWSAStartup.Call(
uintptr(wVersionRequested),
uintptr(lpWSAData),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // INTfunction WSAStartup(
wVersionRequested: Word; // WORD
lpWSAData: Pointer // WSADATA* out
): Integer; stdcall;
external 'WS2_32.dll' name 'WSAStartup';result := DllCall("WS2_32\WSAStartup"
, "UShort", wVersionRequested ; WORD
, "Ptr", lpWSAData ; WSADATA* out
, "Int") ; return: INT●WSAStartup(wVersionRequested, lpWSAData) = DLL("WS2_32.dll", "int WSAStartup(int, void*)")
# 呼び出し: WSAStartup(wVersionRequested, lpWSAData)
# wVersionRequested : WORD -> "int"
# lpWSAData : WSADATA* out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "ws2_32" fn WSAStartup(
wVersionRequested: u16, // WORD
lpWSAData: [*c]WSADATA // WSADATA* out
) callconv(std.os.windows.WINAPI) i32;proc WSAStartup(
wVersionRequested: uint16, # WORD
lpWSAData: ptr WSADATA # WSADATA* out
): int32 {.importc: "WSAStartup", stdcall, dynlib: "WS2_32.dll".}pragma(lib, "ws2_32");
extern(Windows)
int WSAStartup(
ushort wVersionRequested, // WORD
WSADATA* lpWSAData // WSADATA* out
);ccall((:WSAStartup, "WS2_32.dll"), stdcall, Int32,
(UInt16, Ptr{WSADATA}),
wVersionRequested, lpWSAData)
# wVersionRequested : WORD -> UInt16
# lpWSAData : WSADATA* out -> Ptr{WSADATA}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
int32_t WSAStartup(
uint16_t wVersionRequested,
void* lpWSAData);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSAStartup(wVersionRequested, lpWSAData)
-- wVersionRequested : WORD
-- lpWSAData : WSADATA* out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSAStartup = lib.func('__stdcall', 'WSAStartup', 'int32_t', ['uint16_t', 'void *']);
// WSAStartup(wVersionRequested, lpWSAData)
// wVersionRequested : WORD -> 'uint16_t'
// lpWSAData : WSADATA* out -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("WS2_32.dll", {
WSAStartup: { parameters: ["u16", "pointer"], result: "i32" },
});
// lib.symbols.WSAStartup(wVersionRequested, lpWSAData)
// wVersionRequested : WORD -> "u16"
// lpWSAData : WSADATA* out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t WSAStartup(
uint16_t wVersionRequested,
void* lpWSAData);
C, "WS2_32.dll");
// $ffi->WSAStartup(wVersionRequested, lpWSAData);
// wVersionRequested : WORD
// lpWSAData : WSADATA* out
// 構造体/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);
int WSAStartup(
short wVersionRequested, // WORD
Pointer lpWSAData // WSADATA* out
);
}@[Link("ws2_32")]
lib LibWS2_32
fun WSAStartup = WSAStartup(
wVersionRequested : UInt16, # WORD
lpWSAData : WSADATA* # WSADATA* out
) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef WSAStartupNative = Int32 Function(Uint16, Pointer<Void>);
typedef WSAStartupDart = int Function(int, Pointer<Void>);
final WSAStartup = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<WSAStartupNative, WSAStartupDart>('WSAStartup');
// wVersionRequested : WORD -> Uint16
// lpWSAData : WSADATA* out -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function WSAStartup(
wVersionRequested: Word; // WORD
lpWSAData: Pointer // WSADATA* out
): Integer; stdcall;
external 'WS2_32.dll' name 'WSAStartup';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "WSAStartup"
c_WSAStartup :: Word16 -> Ptr () -> IO Int32
-- wVersionRequested : WORD -> Word16
-- lpWSAData : WSADATA* out -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let wsastartup =
foreign "WSAStartup"
(uint16_t @-> (ptr void) @-> returning int32_t)
(* wVersionRequested : WORD -> uint16_t *)
(* lpWSAData : WSADATA* out -> (ptr void) *)
(* 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 ("WSAStartup" wsastartup :convention :stdcall) :int32
(w-version-requested :uint16) ; WORD
(lp-wsadata :pointer)) ; WSADATA* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $WSAStartup = Win32::API::More->new('WS2_32',
'int WSAStartup(WORD wVersionRequested, LPVOID lpWSAData)');
# my $ret = $WSAStartup->Call($wVersionRequested, $lpWSAData);
# wVersionRequested : WORD -> WORD
# lpWSAData : WSADATA* out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- f WSACleanup — Winsock DLLの利用を終了し資源を解放する。
- f WSAGetLastError — 直前のソケット操作のエラーコードを取得する。
- f send — 接続ソケットへデータを送信する。
- f sendto — 指定アドレス宛にソケットでデータを送信する。