WSAPoll
関数シグネチャ
// WS2_32.dll
#include <windows.h>
INT WSAPoll(
WSAPOLLFD* fdArray,
DWORD fds,
INT timeout
);パラメーター
| 名前 | 型 | 方向 | 説明 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| fdArray | WSAPOLLFD* | inout | 状態を要求する socket のセットを指定する、1 つ以上の POLLFD 構造体の配列です。この配列には、有効な socket を持つ構造体が少なくとも 1 つ含まれている必要があります。戻り時に、このパラメーターは、状態照会条件に一致する各 socket について revents 状態フラグメンバーが設定された、更新済みの socket を受け取ります。 | ||||||||
| fds | DWORD | in | fdarray 内の WSAPOLLFD 構造体の数です。これは、状態を要求する socket の数と必ずしも一致しません。 | ||||||||
| timeout | INT | in | 待機動作を指定する値で、次の値に基づきます。
|
戻り値の型: INT
公式ドキュメント
WSAPoll 関数は、1 つ以上の socket の状態を判定します。
戻り値
次のいずれかの値を返します。
| 戻り値 | 説明 |
|---|---|
| 0 | タイマーが満了する前に、照会された状態にある socket がありませんでした。 |
| 0 より大きい | fdarray 内の要素のうち、POLLFD 構造体の revents メンバーが 0 以外である要素の数です。 |
| SOCKET_ERROR | エラーが発生しました。WSAGetLastError 関数を呼び出して、拡張エラーコードを取得してください。 |
| 拡張エラーコード | 意味 |
|---|---|
| ネットワークサブシステムに障害が発生しました。 | |
| ユーザー入力パラメーターの読み取り中に例外が発生しました。 | |
| 無効なパラメーターが渡されました。このエラーは、socket の状態を要求する際に、fdarray パラメーターが指す WSAPOLLFD 構造体に問題がある場合に返されます。また、fdarray パラメーターが指すいずれの WSAPOLLFD 構造体の fd メンバーに指定された socket も有効でなかった場合にも、このエラーが返されます。 | |
| 関数が十分なメモリを割り当てられませんでした。 |
解説(Remarks)
WSAPoll 関数は、Windows Vista 以降で定義されています。
fdarray パラメーターは WSAPOLLFD 構造体を指します。アプリケーションは、WSAPOLLFD 構造体の events メンバーに適切なフラグを設定して、対応する各 socket について要求する状態の種類を指定します。WSAPoll 関数は、socket の状態を WSAPOLLFD 構造体の revents メンバーで返します。
各 socket について、呼び出し元は読み取りまたは書き込み状態に関する情報を要求できます。エラー条件は常に返されるため、それらに関する情報を要求する必要はありません。
状態が要求された socket は、fdarray パラメーターが指す WSAPOLLFD 構造体で報告されます。これらの条件を満たさず、エラー条件もないすべての socket は、対応する revents メンバーが 0 に設定されます。
ある socket の状態を要求する際、その socket について WSAPOLLFD 構造体には、次のフラグを組み合わせて設定できます。
| フラグ | 説明 |
|---|---|
| POLLPRI | 優先データをブロックせずに読み取れます。このフラグは Microsoft Winsock プロバイダーではサポートされていません。 |
| POLLRDBAND | 優先帯域 (帯域外) データをブロックせずに読み取れます。 |
| POLLRDNORM | 通常データをブロックせずに読み取れます。 |
| POLLWRNORM | 通常データをブロックせずに書き込めます。 |
POLLIN フラグは、POLLRDNORM と POLLRDBAND のフラグ値の組み合わせとして定義されます。POLLOUT フラグは、POLLWRNORM フラグ値と同じものとして定義されます。
WSAPOLLFD 構造体には、Winsock プロバイダーがサポートする上記フラグの組み合わせのみを含める必要があります。それ以外の値はエラーとみなされ、WSAPoll は SOCKET_ERROR を返します。続いて WSAGetLastError 関数を呼び出すと、拡張エラーコード WSAEINVAL が取得されます。Microsoft Winsock プロバイダーで socket に POLLPRI フラグが設定されている場合、WSAPoll 関数は失敗します。
socket の状態を示すために、fdarray パラメーターが指す WSAPOLLFD 構造体の revents メンバーには、次のフラグが設定されることがあります。
| フラグ | 説明 |
|---|---|
| POLLERR | エラーが発生しました。 |
| POLLHUP | ストリーム指向の接続が切断または中断されました。 |
| POLLNVAL | 無効な socket が使用されました。 |
| POLLPRI | 優先データをブロックせずに読み取れます。このフラグは Microsoft Winsock プロバイダーでは返されません。 |
| POLLRDBAND | 優先帯域 (帯域外) データをブロックせずに読み取れます。 |
| POLLRDNORM | 通常データをブロックせずに読み取れます。 |
| POLLWRNORM | 通常データをブロックせずに書き込めます。 |
TCP および UDP socket に関して:
- 受信データが利用可能なとき、通常データとして WSAPOLLFD 構造体に POLLRDNORM で示されます。
- WSAPOLLFD 構造体に示されている場合、その後の recv 操作はブロックせずに完了することが保証されます。
- 送信が可能なとき、WSAPOLLFD 構造体に POLLWRNORM で示されます。
- 受信接続が保留中のとき、WSAPOLLFD 構造体に POLLRDNORM で示されます。その後の accept の呼び出しは、ブロックせずに完了することが保証されます。
- 帯域外データが利用可能なとき、WSAPOLLFD 構造体に POLLRDBAND で示されます。
- リモートピアが send 操作をシャットダウンしたとき (TCP FIN を受信したとき)、WSAPOLLFD 構造体に示されます。その後の recv 関数の要求は、0 バイトを返します。
- リモートピアが正常な切断を開始したとき、WSAPOLLFD 構造体に示されます。
- リモートピアが突然切断したとき、WSAPOLLFD 構造体で返されます。
- ローカル socket がクローズされたとき、WSAPOLLFD 構造体に示されます。
fdarray 内の要素 (socket ではない) の数は nfds で示されます。fdarray のメンバーのうち、fd メンバーが負の値に設定されているものは無視され、戻り時にその revents は POLLNVAL に設定されます。この動作は、固定の fdarray 割り当てを維持し、未使用エントリを削除するために配列を圧縮したり、メモリを再割り当てしたりしないアプリケーションにとって有用です。WSAPoll を呼び出す前に、いずれの要素についても revents をクリアする必要はありません。
timeout 引数は、関数が戻る前にどれだけ待機するかを指定します。正の値は、戻る前に待機するミリ秒数を表します。値が 0 の場合、WSAPoll は即座に戻ります。負の値は、WSAPoll が無期限に待機することを示します。
Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストアアプリでサポートされています。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// WS2_32.dll
#include <windows.h>
INT WSAPoll(
WSAPOLLFD* fdArray,
DWORD fds,
INT timeout
);[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int WSAPoll(
IntPtr fdArray, // WSAPOLLFD* in/out
uint fds, // DWORD
int timeout // INT
);<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSAPoll(
fdArray As IntPtr, ' WSAPOLLFD* in/out
fds As UInteger, ' DWORD
timeout As Integer ' INT
) As Integer
End Function' fdArray : WSAPOLLFD* in/out
' fds : DWORD
' timeout : INT
Declare PtrSafe Function WSAPoll Lib "ws2_32" ( _
ByVal fdArray As LongPtr, _
ByVal fds As Long, _
ByVal timeout As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
WSAPoll = ctypes.windll.ws2_32.WSAPoll
WSAPoll.restype = ctypes.c_int
WSAPoll.argtypes = [
ctypes.c_void_p, # fdArray : WSAPOLLFD* in/out
wintypes.DWORD, # fds : DWORD
ctypes.c_int, # timeout : INT
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('WS2_32.dll')
WSAPoll = Fiddle::Function.new(
lib['WSAPoll'],
[
Fiddle::TYPE_VOIDP, # fdArray : WSAPOLLFD* in/out
-Fiddle::TYPE_INT, # fds : DWORD
Fiddle::TYPE_INT, # timeout : INT
],
Fiddle::TYPE_INT)#[link(name = "ws2_32")]
extern "system" {
fn WSAPoll(
fdArray: *mut WSAPOLLFD, // WSAPOLLFD* in/out
fds: u32, // DWORD
timeout: i32 // INT
) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern int WSAPoll(IntPtr fdArray, uint fds, int timeout);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSAPoll' -Namespace Win32 -PassThru
# $api::WSAPoll(fdArray, fds, timeout)#uselib "WS2_32.dll"
#func global WSAPoll "WSAPoll" sptr, sptr, sptr
; WSAPoll varptr(fdArray), fds, timeout ; 戻り値は stat
; fdArray : WSAPOLLFD* in/out -> "sptr"
; fds : DWORD -> "sptr"
; timeout : INT -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "WS2_32.dll" #cfunc global WSAPoll "WSAPoll" var, int, int ; res = WSAPoll(fdArray, fds, timeout) ; fdArray : WSAPOLLFD* in/out -> "var" ; fds : DWORD -> "int" ; timeout : INT -> "int" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "WS2_32.dll" #cfunc global WSAPoll "WSAPoll" sptr, int, int ; res = WSAPoll(varptr(fdArray), fds, timeout) ; fdArray : WSAPOLLFD* in/out -> "sptr" ; fds : DWORD -> "int" ; timeout : INT -> "int" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; INT WSAPoll(WSAPOLLFD* fdArray, DWORD fds, INT timeout) #uselib "WS2_32.dll" #cfunc global WSAPoll "WSAPoll" var, int, int ; res = WSAPoll(fdArray, fds, timeout) ; fdArray : WSAPOLLFD* in/out -> "var" ; fds : DWORD -> "int" ; timeout : INT -> "int" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; INT WSAPoll(WSAPOLLFD* fdArray, DWORD fds, INT timeout) #uselib "WS2_32.dll" #cfunc global WSAPoll "WSAPoll" intptr, int, int ; res = WSAPoll(varptr(fdArray), fds, timeout) ; fdArray : WSAPOLLFD* in/out -> "intptr" ; fds : DWORD -> "int" ; timeout : INT -> "int" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
procWSAPoll = ws2_32.NewProc("WSAPoll")
)
// fdArray (WSAPOLLFD* in/out), fds (DWORD), timeout (INT)
r1, _, err := procWSAPoll.Call(
uintptr(fdArray),
uintptr(fds),
uintptr(timeout),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // INTfunction WSAPoll(
fdArray: Pointer; // WSAPOLLFD* in/out
fds: DWORD; // DWORD
timeout: Integer // INT
): Integer; stdcall;
external 'WS2_32.dll' name 'WSAPoll';result := DllCall("WS2_32\WSAPoll"
, "Ptr", fdArray ; WSAPOLLFD* in/out
, "UInt", fds ; DWORD
, "Int", timeout ; INT
, "Int") ; return: INT●WSAPoll(fdArray, fds, timeout) = DLL("WS2_32.dll", "int WSAPoll(void*, dword, int)")
# 呼び出し: WSAPoll(fdArray, fds, timeout)
# fdArray : WSAPOLLFD* in/out -> "void*"
# fds : DWORD -> "dword"
# timeout : INT -> "int"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "ws2_32" fn WSAPoll(
fdArray: [*c]WSAPOLLFD, // WSAPOLLFD* in/out
fds: u32, // DWORD
timeout: i32 // INT
) callconv(std.os.windows.WINAPI) i32;proc WSAPoll(
fdArray: ptr WSAPOLLFD, # WSAPOLLFD* in/out
fds: uint32, # DWORD
timeout: int32 # INT
): int32 {.importc: "WSAPoll", stdcall, dynlib: "WS2_32.dll".}pragma(lib, "ws2_32");
extern(Windows)
int WSAPoll(
WSAPOLLFD* fdArray, // WSAPOLLFD* in/out
uint fds, // DWORD
int timeout // INT
);ccall((:WSAPoll, "WS2_32.dll"), stdcall, Int32,
(Ptr{WSAPOLLFD}, UInt32, Int32),
fdArray, fds, timeout)
# fdArray : WSAPOLLFD* in/out -> Ptr{WSAPOLLFD}
# fds : DWORD -> UInt32
# timeout : INT -> Int32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
int32_t WSAPoll(
void* fdArray,
uint32_t fds,
int32_t timeout);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSAPoll(fdArray, fds, timeout)
-- fdArray : WSAPOLLFD* in/out
-- fds : DWORD
-- timeout : INT
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSAPoll = lib.func('__stdcall', 'WSAPoll', 'int32_t', ['void *', 'uint32_t', 'int32_t']);
// WSAPoll(fdArray, fds, timeout)
// fdArray : WSAPOLLFD* in/out -> 'void *'
// fds : DWORD -> 'uint32_t'
// timeout : INT -> 'int32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("WS2_32.dll", {
WSAPoll: { parameters: ["pointer", "u32", "i32"], result: "i32" },
});
// lib.symbols.WSAPoll(fdArray, fds, timeout)
// fdArray : WSAPOLLFD* in/out -> "pointer"
// fds : DWORD -> "u32"
// timeout : INT -> "i32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t WSAPoll(
void* fdArray,
uint32_t fds,
int32_t timeout);
C, "WS2_32.dll");
// $ffi->WSAPoll(fdArray, fds, timeout);
// fdArray : WSAPOLLFD* in/out
// fds : DWORD
// timeout : INT
// 構造体/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 WSAPoll(
Pointer fdArray, // WSAPOLLFD* in/out
int fds, // DWORD
int timeout // INT
);
}@[Link("ws2_32")]
lib LibWS2_32
fun WSAPoll = WSAPoll(
fdArray : WSAPOLLFD*, # WSAPOLLFD* in/out
fds : UInt32, # DWORD
timeout : Int32 # INT
) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef WSAPollNative = Int32 Function(Pointer<Void>, Uint32, Int32);
typedef WSAPollDart = int Function(Pointer<Void>, int, int);
final WSAPoll = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<WSAPollNative, WSAPollDart>('WSAPoll');
// fdArray : WSAPOLLFD* in/out -> Pointer<Void>
// fds : DWORD -> Uint32
// timeout : INT -> Int32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function WSAPoll(
fdArray: Pointer; // WSAPOLLFD* in/out
fds: DWORD; // DWORD
timeout: Integer // INT
): Integer; stdcall;
external 'WS2_32.dll' name 'WSAPoll';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "WSAPoll"
c_WSAPoll :: Ptr () -> Word32 -> Int32 -> IO Int32
-- fdArray : WSAPOLLFD* in/out -> Ptr ()
-- fds : DWORD -> Word32
-- timeout : INT -> Int32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let wsapoll =
foreign "WSAPoll"
((ptr void) @-> uint32_t @-> int32_t @-> returning int32_t)
(* fdArray : WSAPOLLFD* in/out -> (ptr void) *)
(* fds : DWORD -> uint32_t *)
(* timeout : INT -> int32_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 ("WSAPoll" wsapoll :convention :stdcall) :int32
(fd-array :pointer) ; WSAPOLLFD* in/out
(fds :uint32) ; DWORD
(timeout :int32)) ; INT
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $WSAPoll = Win32::API::More->new('WS2_32',
'int WSAPoll(LPVOID fdArray, DWORD fds, int timeout)');
# my $ret = $WSAPoll->Call($fdArray, $fds, $timeout);
# fdArray : WSAPOLLFD* in/out -> LPVOID
# fds : DWORD -> DWORD
# timeout : INT -> int
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- f WSAGetLastError — 直前のソケット操作のエラーコードを取得する。