WSAConnectByList
関数シグネチャ
// WS2_32.dll
#include <windows.h>
BOOL WSAConnectByList(
SOCKET s,
SOCKET_ADDRESS_LIST* SocketAddress,
DWORD* LocalAddressLength, // optional
SOCKADDR* LocalAddress, // optional
DWORD* RemoteAddressLength, // optional
SOCKADDR* RemoteAddress, // optional
const TIMEVAL* timeout, // optional
OVERLAPPED* Reserved // optional
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| s | SOCKET | in | バインドされておらず、接続もされていないソケットを識別するディスクリプタ。接続を確立する他の Winsock 呼び出し(たとえば WSAConnect)とは異なり、 WSAConnectByList 関数は バインドされていないソケットを必要とする点に注意してください。 |
| SocketAddress | SOCKET_ADDRESS_LIST* | in | ピアへの接続に使用しうる宛先アドレスとポートの組を表す SOCKET_ADDRESS_LIST 構造体へのポインタ。SOCKET_ADDRESS_LIST 内の各 SOCKET_ADDRESS 構造体にポート番号を設定するのは、 アプリケーションの責任です。 |
| LocalAddressLength | DWORD* | inoutoptional | 入力時には、呼び出し側が用意した LocalAddress バッファのサイズ(バイト単位)へのポインタ。 出力時には、呼び出しが正常に完了したときにシステムが LocalAddress バッファに格納したローカルアドレスの SOCKADDR のサイズ(バイト単位)へのポインタ。 |
| LocalAddress | SOCKADDR* | outoptional | 接続のローカルアドレスを受け取る SOCKADDR 構造体へのポインタ。 このパラメーターのサイズは LocalAddressLength で返されるサイズと正確に一致します。 これは getsockname 関数で返される情報と同じです。 このパラメーターには NULL を指定でき、その場合は LocalAddressLength パラメーターは 無視されます。 |
| RemoteAddressLength | DWORD* | inoutoptional | 入力時には、呼び出し側が用意した RemoteAddress バッファのサイズ(バイト単位)へのポインタ。 出力時には、呼び出しが正常に完了したときにシステムが RemoteAddress バッファに格納したリモートアドレスの SOCKADDR のサイズ(バイト単位)へのポインタ。 |
| RemoteAddress | SOCKADDR* | outoptional | 接続のリモートアドレスを受け取る SOCKADDR 構造体へのポインタ。 これは getpeername 関数で返される情報と同じです。このパラメーターには NULL を指定でき、 その場合は RemoteAddressLength は無視されます。 |
| timeout | TIMEVAL* | inoptional | 呼び出しを中止するまでに、リモートアプリケーションからの応答を待つ時間(ミリ秒単位)。 このパラメーターには NULL を指定でき、その場合 WSAConnectByList は、 接続が正常に確立されるか、または接続を試行してすべてのローカル/リモートアドレスの組で失敗した後に 完了します。 |
| Reserved | OVERLAPPED* | optional | 将来の実装のために予約されています。このパラメーターは NULL に設定する必要があります。 |
戻り値の型: BOOL
公式ドキュメント
宛先アドレス(ホスト名とポート)の集合で表される、複数の接続先候補のうちの 1 つへの接続を確立します。
戻り値
接続が確立された場合、 WSAConnectByList は TRUE を返し、 これらのバッファが呼び出し側から指定されていれば LocalAddress および RemoteAddress パラメーターが 設定されます。
呼び出しが失敗した場合は FALSE が返されます。 その後 WSAGetLastError を呼び出して 詳細なエラー情報を取得できます。
| 戻り値コード | 説明 |
|---|---|
|
nodename パラメーターとして渡されたホストに到達できませんでした。 |
|
無効なパラメーターが関数に渡されました。Reserved パラメーターは NULL でなければなりません。 |
|
十分なメモリを割り当てられませんでした。 |
|
無効なソケットが関数に渡されました。s パラメーターは INVALID_SOCKET または NULL であってはなりません。 |
|
timeout パラメーターで指定した時間を超えるまでに、リモートアプリケーションからの 応答を受信できませんでした。 |
解説(Remarks)
WSAConnectByList は WSAConnectByName 関数に似ています。単一のホスト名とサービス名(ポート)を 受け取る代わりに、WSAConnectByList はアドレスのリスト(ホスト アドレスとポート)を受け取り、そのうちの 1 つのアドレスに接続します。 WSAConnectByList 関数は、 アプリケーションが候補ノードのリストの中から利用可能な任意のノードに接続する必要がある、 ピアツーピアの共同作業シナリオをサポートするように設計されています。WSAConnectByList は IPv6 版と IPv4 版の両方に対応しています。
接続先候補の集合は、アドレスのリストとして 呼び出し側から提供されます。WSAConnectByList は 単に複数の宛先アドレスのうち 1 つへの接続を試みる以上のことを行います。具体的には、この関数は 呼び出し側から渡されたすべてのリモートアドレスとすべてのローカルアドレスを受け取り、 成功する可能性が最も高いアドレスの組から順に接続を試みます。このように、 WSAConnectByList は接続が可能であれば必ず 接続が確立されることを保証するだけでなく、接続の確立にかかる時間も最小限に 抑えます。
呼び出し側は LocalAddress および RemoteAddress バッファとその長さを指定して、接続が正常に確立されたローカルおよびリモートアドレスを 特定できます。
timeout パラメーターにより、呼び出し側は接続の確立に関数が費やす時間を 制限できます。内部的には、 WSAConnectByList は複数の操作(接続試行)を実行します。各操作の合間に timeout パラメーターをチェックして timeout を超えていないかを確認し、 超えている場合は呼び出しを中止します。なお、個々の操作(connect)は timeout を超えても いったん開始されると中断されないため、WSAConnectByList の呼び出しが タイムアウトするまでに、timeout パラメーターで指定した値より長くかかる場合があります。
WSAConnectByList には制限があります。SOCK_STREAM 型などの コネクション指向のソケットでのみ動作します。この関数はオーバーラップ I/O や 非ブロッキング動作をサポートしません。WSAConnectByList は ソケットが非ブロッキングモードであってもブロックします。 WSAConnectByList は、呼び出し側から提供された各アドレスに 1 つずつ接続を試みます。これらの接続試行はそれぞれ異なるエラーコードで失敗する可能性があります。 返せるエラーコードは 1 つだけであるため、返される値は最後の接続試行のエラーコードに なります。
この関数が受け取る単一のアドレスリストに IPv6 と IPv4 の両方のアドレスを渡せるようにするには、 関数を呼び出す前に次の手順を実行する必要があります。
- WSAConnectByList を呼び出す前に、AF_INET6 アドレスファミリ用に作成したソケットで setsockopt 関数を呼び出して IPV6_V6ONLY ソケット オプションを無効にする必要があります。これは、ソケットに対して setsockopt 関数を呼び出し、 level パラメーターを IPPROTO_IPV6 (IPPROTO_IPV6 Socket Options を参照)、 optname パラメーターを IPV6_V6ONLY、 optvalue パラメーターの値を 0 に設定することで実現します。
- すべての IPv4 アドレスは、IPv6 のみのアプリケーションが IPv4 ノードと通信できるようにする、IPv4 マップ IPv6 アドレス形式で表す必要があります。IPv4 マップ IPv6 アドレス形式により、IPv4 ノードの IPv4 アドレスを IPv6 アドレスとして表現できます。IPv4 アドレスは IPv6 アドレスの下位 32 ビットにエンコードされ、上位 96 ビットには固定プレフィックス 0:0:0:0:0:FFFF が格納されます。IPv4 マップ IPv6 アドレス形式は RFC 4291 で規定されています。詳細については、www.ietf.org/rfc/rfc4291.txt を参照してください。Mstcpip.h 内の IN6ADDR_SETV4MAPPED マクロを使用して、IPv4 アドレスを必要な IPv4 マップ IPv6 アドレス形式に変換できます。
SocketAddressList パラメーターで渡されるポインタの配列は、汎用的なデータ型である SOCKET_ADDRESS 構造体の配列を指します。RemoteAddress および LocalAddress パラメーターも SOCKADDR 構造体を指します。WSAConnectByList を呼び出すときは、 実際には使用するネットワークプロトコルまたはアドレスファミリに固有のソケットアドレス型が これらのパラメーターに渡されることが想定されています。したがって IPv4 アドレスの場合は、 sockaddr_in 構造体へのポインタをパラメーターとして渡すときに SOCKADDR へのポインタに キャストします。IPv6 アドレスの場合は、sockaddr_in6 構造体へのポインタを パラメーターとして渡すときに SOCKADDR へのポインタにキャストします。 SocketAddressList パラメーターには、IPv4 アドレスと IPv6 アドレスが混在した ポインタを含めることができます。つまり、一部の SOCKET_ADDRESS ポインタは sockaddr_in 構造体を指し、他は sockaddr_in6 構造体を指すことが できます。IPv6 アドレスが使用される可能性がある場合は、RemoteAddress および LocalAddress パラメーターは sockaddr_in6 構造体を指し、SOCKADDR 構造体にキャストする必要があります。 RemoteAddressLength および LocalAddressLength パラメーターは、これらのより大きな 構造体の長さを表す必要があります。
WSAConnectByList 関数が TRUE を返すと、ソケット s は接続済みソケットの既定の状態になります。ソケット s では、SO_UPDATE_CONNECT_CONTEXT がソケットに設定されるまで、以前に設定したプロパティやオプションは有効になりません。SO_UPDATE_CONNECT_CONTEXT オプションを設定するには setsockopt 関数を使用します。
次に例を示します。
//Need to #include <mswsock.h> for SO_UPDATE_CONNECT_CONTEXT
int iResult = 0;
iResult = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );
Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows Store アプリでサポートされます。
例
WSAConnectByList を使用して接続を確立します。
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
SOCKET
OpenAndConnect(SOCKET_ADDRESS_LIST *AddressList)
{
SOCKET ConnSocket = INVALID_SOCKET;
int ipv6only = 0;
int iResult;
BOOL bSuccess;
SOCKADDR_STORAGE LocalAddr = {0};
SOCKADDR_STORAGE RemoteAddr = {0};
DWORD dwLocalAddr = sizeof(LocalAddr);
DWORD dwRemoteAddr = sizeof(RemoteAddr);
ConnSocket = socket(AF_INET6, SOCK_STREAM, 0);
if (ConnSocket == INVALID_SOCKET){
return INVALID_SOCKET;
}
iResult = setsockopt(ConnSocket, IPPROTO_IPV6,
IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
if (iResult == SOCKET_ERROR){
closesocket(ConnSocket);
return INVALID_SOCKET;
}
// AddressList may contain IPv6 and/or IPv4Mapped addresses
bSuccess = WSAConnectByList(ConnSocket,
AddressList,
&dwLocalAddr,
(SOCKADDR*)&LocalAddr,
&dwRemoteAddr,
(SOCKADDR*)&RemoteAddr,
NULL,
NULL);
if (bSuccess){
return ConnSocket;
} else {
return INVALID_SOCKET;
}
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// WS2_32.dll
#include <windows.h>
BOOL WSAConnectByList(
SOCKET s,
SOCKET_ADDRESS_LIST* SocketAddress,
DWORD* LocalAddressLength, // optional
SOCKADDR* LocalAddress, // optional
DWORD* RemoteAddressLength, // optional
SOCKADDR* RemoteAddress, // optional
const TIMEVAL* timeout, // optional
OVERLAPPED* Reserved // optional
);[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool WSAConnectByList(
UIntPtr s, // SOCKET
IntPtr SocketAddress, // SOCKET_ADDRESS_LIST*
IntPtr LocalAddressLength, // DWORD* optional, in/out
IntPtr LocalAddress, // SOCKADDR* optional, out
IntPtr RemoteAddressLength, // DWORD* optional, in/out
IntPtr RemoteAddress, // SOCKADDR* optional, out
IntPtr timeout, // TIMEVAL* optional
IntPtr Reserved // OVERLAPPED* optional
);<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSAConnectByList(
s As UIntPtr, ' SOCKET
SocketAddress As IntPtr, ' SOCKET_ADDRESS_LIST*
LocalAddressLength As IntPtr, ' DWORD* optional, in/out
LocalAddress As IntPtr, ' SOCKADDR* optional, out
RemoteAddressLength As IntPtr, ' DWORD* optional, in/out
RemoteAddress As IntPtr, ' SOCKADDR* optional, out
timeout As IntPtr, ' TIMEVAL* optional
Reserved As IntPtr ' OVERLAPPED* optional
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function' s : SOCKET
' SocketAddress : SOCKET_ADDRESS_LIST*
' LocalAddressLength : DWORD* optional, in/out
' LocalAddress : SOCKADDR* optional, out
' RemoteAddressLength : DWORD* optional, in/out
' RemoteAddress : SOCKADDR* optional, out
' timeout : TIMEVAL* optional
' Reserved : OVERLAPPED* optional
Declare PtrSafe Function WSAConnectByList Lib "ws2_32" ( _
ByVal s As LongPtr, _
ByVal SocketAddress As LongPtr, _
ByVal LocalAddressLength As LongPtr, _
ByVal LocalAddress As LongPtr, _
ByVal RemoteAddressLength As LongPtr, _
ByVal RemoteAddress As LongPtr, _
ByVal timeout As LongPtr, _
ByVal Reserved As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
WSAConnectByList = ctypes.windll.ws2_32.WSAConnectByList
WSAConnectByList.restype = wintypes.BOOL
WSAConnectByList.argtypes = [
ctypes.c_size_t, # s : SOCKET
ctypes.c_void_p, # SocketAddress : SOCKET_ADDRESS_LIST*
ctypes.POINTER(wintypes.DWORD), # LocalAddressLength : DWORD* optional, in/out
ctypes.c_void_p, # LocalAddress : SOCKADDR* optional, out
ctypes.POINTER(wintypes.DWORD), # RemoteAddressLength : DWORD* optional, in/out
ctypes.c_void_p, # RemoteAddress : SOCKADDR* optional, out
ctypes.c_void_p, # timeout : TIMEVAL* optional
ctypes.c_void_p, # Reserved : OVERLAPPED* optional
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('WS2_32.dll')
WSAConnectByList = Fiddle::Function.new(
lib['WSAConnectByList'],
[
Fiddle::TYPE_UINTPTR_T, # s : SOCKET
Fiddle::TYPE_VOIDP, # SocketAddress : SOCKET_ADDRESS_LIST*
Fiddle::TYPE_VOIDP, # LocalAddressLength : DWORD* optional, in/out
Fiddle::TYPE_VOIDP, # LocalAddress : SOCKADDR* optional, out
Fiddle::TYPE_VOIDP, # RemoteAddressLength : DWORD* optional, in/out
Fiddle::TYPE_VOIDP, # RemoteAddress : SOCKADDR* optional, out
Fiddle::TYPE_VOIDP, # timeout : TIMEVAL* optional
Fiddle::TYPE_VOIDP, # Reserved : OVERLAPPED* optional
],
Fiddle::TYPE_INT)#[link(name = "ws2_32")]
extern "system" {
fn WSAConnectByList(
s: usize, // SOCKET
SocketAddress: *mut SOCKET_ADDRESS_LIST, // SOCKET_ADDRESS_LIST*
LocalAddressLength: *mut u32, // DWORD* optional, in/out
LocalAddress: *mut SOCKADDR, // SOCKADDR* optional, out
RemoteAddressLength: *mut u32, // DWORD* optional, in/out
RemoteAddress: *mut SOCKADDR, // SOCKADDR* optional, out
timeout: *const TIMEVAL, // TIMEVAL* optional
Reserved: *mut OVERLAPPED // OVERLAPPED* optional
) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern bool WSAConnectByList(UIntPtr s, IntPtr SocketAddress, IntPtr LocalAddressLength, IntPtr LocalAddress, IntPtr RemoteAddressLength, IntPtr RemoteAddress, IntPtr timeout, IntPtr Reserved);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSAConnectByList' -Namespace Win32 -PassThru
# $api::WSAConnectByList(s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)#uselib "WS2_32.dll"
#func global WSAConnectByList "WSAConnectByList" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr
; WSAConnectByList s, varptr(SocketAddress), varptr(LocalAddressLength), varptr(LocalAddress), varptr(RemoteAddressLength), varptr(RemoteAddress), varptr(timeout), varptr(Reserved) ; 戻り値は stat
; s : SOCKET -> "sptr"
; SocketAddress : SOCKET_ADDRESS_LIST* -> "sptr"
; LocalAddressLength : DWORD* optional, in/out -> "sptr"
; LocalAddress : SOCKADDR* optional, out -> "sptr"
; RemoteAddressLength : DWORD* optional, in/out -> "sptr"
; RemoteAddress : SOCKADDR* optional, out -> "sptr"
; timeout : TIMEVAL* optional -> "sptr"
; Reserved : OVERLAPPED* optional -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "WS2_32.dll" #cfunc global WSAConnectByList "WSAConnectByList" sptr, var, var, var, var, var, var, var ; res = WSAConnectByList(s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved) ; s : SOCKET -> "sptr" ; SocketAddress : SOCKET_ADDRESS_LIST* -> "var" ; LocalAddressLength : DWORD* optional, in/out -> "var" ; LocalAddress : SOCKADDR* optional, out -> "var" ; RemoteAddressLength : DWORD* optional, in/out -> "var" ; RemoteAddress : SOCKADDR* optional, out -> "var" ; timeout : TIMEVAL* optional -> "var" ; Reserved : OVERLAPPED* optional -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "WS2_32.dll" #cfunc global WSAConnectByList "WSAConnectByList" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr ; res = WSAConnectByList(s, varptr(SocketAddress), varptr(LocalAddressLength), varptr(LocalAddress), varptr(RemoteAddressLength), varptr(RemoteAddress), varptr(timeout), varptr(Reserved)) ; s : SOCKET -> "sptr" ; SocketAddress : SOCKET_ADDRESS_LIST* -> "sptr" ; LocalAddressLength : DWORD* optional, in/out -> "sptr" ; LocalAddress : SOCKADDR* optional, out -> "sptr" ; RemoteAddressLength : DWORD* optional, in/out -> "sptr" ; RemoteAddress : SOCKADDR* optional, out -> "sptr" ; timeout : TIMEVAL* optional -> "sptr" ; Reserved : OVERLAPPED* optional -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; BOOL WSAConnectByList(SOCKET s, SOCKET_ADDRESS_LIST* SocketAddress, DWORD* LocalAddressLength, SOCKADDR* LocalAddress, DWORD* RemoteAddressLength, SOCKADDR* RemoteAddress, TIMEVAL* timeout, OVERLAPPED* Reserved) #uselib "WS2_32.dll" #cfunc global WSAConnectByList "WSAConnectByList" intptr, var, var, var, var, var, var, var ; res = WSAConnectByList(s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved) ; s : SOCKET -> "intptr" ; SocketAddress : SOCKET_ADDRESS_LIST* -> "var" ; LocalAddressLength : DWORD* optional, in/out -> "var" ; LocalAddress : SOCKADDR* optional, out -> "var" ; RemoteAddressLength : DWORD* optional, in/out -> "var" ; RemoteAddress : SOCKADDR* optional, out -> "var" ; timeout : TIMEVAL* optional -> "var" ; Reserved : OVERLAPPED* optional -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; BOOL WSAConnectByList(SOCKET s, SOCKET_ADDRESS_LIST* SocketAddress, DWORD* LocalAddressLength, SOCKADDR* LocalAddress, DWORD* RemoteAddressLength, SOCKADDR* RemoteAddress, TIMEVAL* timeout, OVERLAPPED* Reserved) #uselib "WS2_32.dll" #cfunc global WSAConnectByList "WSAConnectByList" intptr, intptr, intptr, intptr, intptr, intptr, intptr, intptr ; res = WSAConnectByList(s, varptr(SocketAddress), varptr(LocalAddressLength), varptr(LocalAddress), varptr(RemoteAddressLength), varptr(RemoteAddress), varptr(timeout), varptr(Reserved)) ; s : SOCKET -> "intptr" ; SocketAddress : SOCKET_ADDRESS_LIST* -> "intptr" ; LocalAddressLength : DWORD* optional, in/out -> "intptr" ; LocalAddress : SOCKADDR* optional, out -> "intptr" ; RemoteAddressLength : DWORD* optional, in/out -> "intptr" ; RemoteAddress : SOCKADDR* optional, out -> "intptr" ; timeout : TIMEVAL* optional -> "intptr" ; Reserved : OVERLAPPED* optional -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
procWSAConnectByList = ws2_32.NewProc("WSAConnectByList")
)
// s (SOCKET), SocketAddress (SOCKET_ADDRESS_LIST*), LocalAddressLength (DWORD* optional, in/out), LocalAddress (SOCKADDR* optional, out), RemoteAddressLength (DWORD* optional, in/out), RemoteAddress (SOCKADDR* optional, out), timeout (TIMEVAL* optional), Reserved (OVERLAPPED* optional)
r1, _, err := procWSAConnectByList.Call(
uintptr(s),
uintptr(SocketAddress),
uintptr(LocalAddressLength),
uintptr(LocalAddress),
uintptr(RemoteAddressLength),
uintptr(RemoteAddress),
uintptr(timeout),
uintptr(Reserved),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // BOOLfunction WSAConnectByList(
s: NativeUInt; // SOCKET
SocketAddress: Pointer; // SOCKET_ADDRESS_LIST*
LocalAddressLength: Pointer; // DWORD* optional, in/out
LocalAddress: Pointer; // SOCKADDR* optional, out
RemoteAddressLength: Pointer; // DWORD* optional, in/out
RemoteAddress: Pointer; // SOCKADDR* optional, out
timeout: Pointer; // TIMEVAL* optional
Reserved: Pointer // OVERLAPPED* optional
): BOOL; stdcall;
external 'WS2_32.dll' name 'WSAConnectByList';result := DllCall("WS2_32\WSAConnectByList"
, "UPtr", s ; SOCKET
, "Ptr", SocketAddress ; SOCKET_ADDRESS_LIST*
, "Ptr", LocalAddressLength ; DWORD* optional, in/out
, "Ptr", LocalAddress ; SOCKADDR* optional, out
, "Ptr", RemoteAddressLength ; DWORD* optional, in/out
, "Ptr", RemoteAddress ; SOCKADDR* optional, out
, "Ptr", timeout ; TIMEVAL* optional
, "Ptr", Reserved ; OVERLAPPED* optional
, "Int") ; return: BOOL●WSAConnectByList(s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved) = DLL("WS2_32.dll", "bool WSAConnectByList(int, void*, void*, void*, void*, void*, void*, void*)")
# 呼び出し: WSAConnectByList(s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
# s : SOCKET -> "int"
# SocketAddress : SOCKET_ADDRESS_LIST* -> "void*"
# LocalAddressLength : DWORD* optional, in/out -> "void*"
# LocalAddress : SOCKADDR* optional, out -> "void*"
# RemoteAddressLength : DWORD* optional, in/out -> "void*"
# RemoteAddress : SOCKADDR* optional, out -> "void*"
# timeout : TIMEVAL* optional -> "void*"
# Reserved : OVERLAPPED* optional -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "ws2_32" fn WSAConnectByList(
s: usize, // SOCKET
SocketAddress: [*c]SOCKET_ADDRESS_LIST, // SOCKET_ADDRESS_LIST*
LocalAddressLength: [*c]u32, // DWORD* optional, in/out
LocalAddress: [*c]SOCKADDR, // SOCKADDR* optional, out
RemoteAddressLength: [*c]u32, // DWORD* optional, in/out
RemoteAddress: [*c]SOCKADDR, // SOCKADDR* optional, out
timeout: [*c]TIMEVAL, // TIMEVAL* optional
Reserved: [*c]OVERLAPPED // OVERLAPPED* optional
) callconv(std.os.windows.WINAPI) i32;proc WSAConnectByList(
s: uint, # SOCKET
SocketAddress: ptr SOCKET_ADDRESS_LIST, # SOCKET_ADDRESS_LIST*
LocalAddressLength: ptr uint32, # DWORD* optional, in/out
LocalAddress: ptr SOCKADDR, # SOCKADDR* optional, out
RemoteAddressLength: ptr uint32, # DWORD* optional, in/out
RemoteAddress: ptr SOCKADDR, # SOCKADDR* optional, out
timeout: ptr TIMEVAL, # TIMEVAL* optional
Reserved: ptr OVERLAPPED # OVERLAPPED* optional
): int32 {.importc: "WSAConnectByList", stdcall, dynlib: "WS2_32.dll".}pragma(lib, "ws2_32");
extern(Windows)
int WSAConnectByList(
size_t s, // SOCKET
SOCKET_ADDRESS_LIST* SocketAddress, // SOCKET_ADDRESS_LIST*
uint* LocalAddressLength, // DWORD* optional, in/out
SOCKADDR* LocalAddress, // SOCKADDR* optional, out
uint* RemoteAddressLength, // DWORD* optional, in/out
SOCKADDR* RemoteAddress, // SOCKADDR* optional, out
TIMEVAL* timeout, // TIMEVAL* optional
OVERLAPPED* Reserved // OVERLAPPED* optional
);ccall((:WSAConnectByList, "WS2_32.dll"), stdcall, Int32,
(Csize_t, Ptr{SOCKET_ADDRESS_LIST}, Ptr{UInt32}, Ptr{SOCKADDR}, Ptr{UInt32}, Ptr{SOCKADDR}, Ptr{TIMEVAL}, Ptr{OVERLAPPED}),
s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
# s : SOCKET -> Csize_t
# SocketAddress : SOCKET_ADDRESS_LIST* -> Ptr{SOCKET_ADDRESS_LIST}
# LocalAddressLength : DWORD* optional, in/out -> Ptr{UInt32}
# LocalAddress : SOCKADDR* optional, out -> Ptr{SOCKADDR}
# RemoteAddressLength : DWORD* optional, in/out -> Ptr{UInt32}
# RemoteAddress : SOCKADDR* optional, out -> Ptr{SOCKADDR}
# timeout : TIMEVAL* optional -> Ptr{TIMEVAL}
# Reserved : OVERLAPPED* optional -> Ptr{OVERLAPPED}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
int32_t WSAConnectByList(
uintptr_t s,
void* SocketAddress,
uint32_t* LocalAddressLength,
void* LocalAddress,
uint32_t* RemoteAddressLength,
void* RemoteAddress,
void* timeout,
void* Reserved);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSAConnectByList(s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
-- s : SOCKET
-- SocketAddress : SOCKET_ADDRESS_LIST*
-- LocalAddressLength : DWORD* optional, in/out
-- LocalAddress : SOCKADDR* optional, out
-- RemoteAddressLength : DWORD* optional, in/out
-- RemoteAddress : SOCKADDR* optional, out
-- timeout : TIMEVAL* optional
-- Reserved : OVERLAPPED* optional
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSAConnectByList = lib.func('__stdcall', 'WSAConnectByList', 'int32_t', ['uintptr_t', 'void *', 'uint32_t *', 'void *', 'uint32_t *', 'void *', 'void *', 'void *']);
// WSAConnectByList(s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
// s : SOCKET -> 'uintptr_t'
// SocketAddress : SOCKET_ADDRESS_LIST* -> 'void *'
// LocalAddressLength : DWORD* optional, in/out -> 'uint32_t *'
// LocalAddress : SOCKADDR* optional, out -> 'void *'
// RemoteAddressLength : DWORD* optional, in/out -> 'uint32_t *'
// RemoteAddress : SOCKADDR* optional, out -> 'void *'
// timeout : TIMEVAL* optional -> 'void *'
// Reserved : OVERLAPPED* optional -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("WS2_32.dll", {
WSAConnectByList: { parameters: ["usize", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer"], result: "i32" },
});
// lib.symbols.WSAConnectByList(s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
// s : SOCKET -> "usize"
// SocketAddress : SOCKET_ADDRESS_LIST* -> "pointer"
// LocalAddressLength : DWORD* optional, in/out -> "pointer"
// LocalAddress : SOCKADDR* optional, out -> "pointer"
// RemoteAddressLength : DWORD* optional, in/out -> "pointer"
// RemoteAddress : SOCKADDR* optional, out -> "pointer"
// timeout : TIMEVAL* optional -> "pointer"
// Reserved : OVERLAPPED* optional -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t WSAConnectByList(
size_t s,
void* SocketAddress,
uint32_t* LocalAddressLength,
void* LocalAddress,
uint32_t* RemoteAddressLength,
void* RemoteAddress,
void* timeout,
void* Reserved);
C, "WS2_32.dll");
// $ffi->WSAConnectByList(s, SocketAddress, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved);
// s : SOCKET
// SocketAddress : SOCKET_ADDRESS_LIST*
// LocalAddressLength : DWORD* optional, in/out
// LocalAddress : SOCKADDR* optional, out
// RemoteAddressLength : DWORD* optional, in/out
// RemoteAddress : SOCKADDR* optional, out
// timeout : TIMEVAL* optional
// Reserved : OVERLAPPED* optional
// 構造体/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);
boolean WSAConnectByList(
long s, // SOCKET
Pointer SocketAddress, // SOCKET_ADDRESS_LIST*
IntByReference LocalAddressLength, // DWORD* optional, in/out
Pointer LocalAddress, // SOCKADDR* optional, out
IntByReference RemoteAddressLength, // DWORD* optional, in/out
Pointer RemoteAddress, // SOCKADDR* optional, out
Pointer timeout, // TIMEVAL* optional
Pointer Reserved // OVERLAPPED* optional
);
}@[Link("ws2_32")]
lib LibWS2_32
fun WSAConnectByList = WSAConnectByList(
s : LibC::SizeT, # SOCKET
SocketAddress : SOCKET_ADDRESS_LIST*, # SOCKET_ADDRESS_LIST*
LocalAddressLength : UInt32*, # DWORD* optional, in/out
LocalAddress : SOCKADDR*, # SOCKADDR* optional, out
RemoteAddressLength : UInt32*, # DWORD* optional, in/out
RemoteAddress : SOCKADDR*, # SOCKADDR* optional, out
timeout : TIMEVAL*, # TIMEVAL* optional
Reserved : OVERLAPPED* # OVERLAPPED* optional
) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef WSAConnectByListNative = Int32 Function(UintPtr, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
typedef WSAConnectByListDart = int Function(int, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
final WSAConnectByList = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<WSAConnectByListNative, WSAConnectByListDart>('WSAConnectByList');
// s : SOCKET -> UintPtr
// SocketAddress : SOCKET_ADDRESS_LIST* -> Pointer<Void>
// LocalAddressLength : DWORD* optional, in/out -> Pointer<Uint32>
// LocalAddress : SOCKADDR* optional, out -> Pointer<Void>
// RemoteAddressLength : DWORD* optional, in/out -> Pointer<Uint32>
// RemoteAddress : SOCKADDR* optional, out -> Pointer<Void>
// timeout : TIMEVAL* optional -> Pointer<Void>
// Reserved : OVERLAPPED* optional -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function WSAConnectByList(
s: NativeUInt; // SOCKET
SocketAddress: Pointer; // SOCKET_ADDRESS_LIST*
LocalAddressLength: Pointer; // DWORD* optional, in/out
LocalAddress: Pointer; // SOCKADDR* optional, out
RemoteAddressLength: Pointer; // DWORD* optional, in/out
RemoteAddress: Pointer; // SOCKADDR* optional, out
timeout: Pointer; // TIMEVAL* optional
Reserved: Pointer // OVERLAPPED* optional
): BOOL; stdcall;
external 'WS2_32.dll' name 'WSAConnectByList';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "WSAConnectByList"
c_WSAConnectByList :: CUIntPtr -> Ptr () -> Ptr Word32 -> Ptr () -> Ptr Word32 -> Ptr () -> Ptr () -> Ptr () -> IO CInt
-- s : SOCKET -> CUIntPtr
-- SocketAddress : SOCKET_ADDRESS_LIST* -> Ptr ()
-- LocalAddressLength : DWORD* optional, in/out -> Ptr Word32
-- LocalAddress : SOCKADDR* optional, out -> Ptr ()
-- RemoteAddressLength : DWORD* optional, in/out -> Ptr Word32
-- RemoteAddress : SOCKADDR* optional, out -> Ptr ()
-- timeout : TIMEVAL* optional -> Ptr ()
-- Reserved : OVERLAPPED* optional -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let wsaconnectbylist =
foreign "WSAConnectByList"
(size_t @-> (ptr void) @-> (ptr uint32_t) @-> (ptr void) @-> (ptr uint32_t) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> returning int32_t)
(* s : SOCKET -> size_t *)
(* SocketAddress : SOCKET_ADDRESS_LIST* -> (ptr void) *)
(* LocalAddressLength : DWORD* optional, in/out -> (ptr uint32_t) *)
(* LocalAddress : SOCKADDR* optional, out -> (ptr void) *)
(* RemoteAddressLength : DWORD* optional, in/out -> (ptr uint32_t) *)
(* RemoteAddress : SOCKADDR* optional, out -> (ptr void) *)
(* timeout : TIMEVAL* optional -> (ptr void) *)
(* Reserved : OVERLAPPED* optional -> (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 ("WSAConnectByList" wsaconnect-by-list :convention :stdcall) :int32
(s :uint64) ; SOCKET
(socket-address :pointer) ; SOCKET_ADDRESS_LIST*
(local-address-length :pointer) ; DWORD* optional, in/out
(local-address :pointer) ; SOCKADDR* optional, out
(remote-address-length :pointer) ; DWORD* optional, in/out
(remote-address :pointer) ; SOCKADDR* optional, out
(timeout :pointer) ; TIMEVAL* optional
(reserved :pointer)) ; OVERLAPPED* optional
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $WSAConnectByList = Win32::API::More->new('WS2_32',
'BOOL WSAConnectByList(WPARAM s, LPVOID SocketAddress, LPVOID LocalAddressLength, LPVOID LocalAddress, LPVOID RemoteAddressLength, LPVOID RemoteAddress, LPVOID timeout, LPVOID Reserved)');
# my $ret = $WSAConnectByList->Call($s, $SocketAddress, $LocalAddressLength, $LocalAddress, $RemoteAddressLength, $RemoteAddress, $timeout, $Reserved);
# s : SOCKET -> WPARAM
# SocketAddress : SOCKET_ADDRESS_LIST* -> LPVOID
# LocalAddressLength : DWORD* optional, in/out -> LPVOID
# LocalAddress : SOCKADDR* optional, out -> LPVOID
# RemoteAddressLength : DWORD* optional, in/out -> LPVOID
# RemoteAddress : SOCKADDR* optional, out -> LPVOID
# timeout : TIMEVAL* optional -> LPVOID
# Reserved : OVERLAPPED* optional -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- s SOCKET_ADDRESS
- f WSAConnect — 接続データやQoS指定付きで相手に接続する。
- f WSAConnectByNameW — ホスト名とサービス名を指定して接続を確立する。
- f WSAGetLastError — 直前のソケット操作のエラーコードを取得する。
- f getaddrinfo — ホスト名やサービス名からアドレス情報を解決する。
- f getpeername — 接続先ソケットのアドレス情報を取得する。
- f getsockname — ソケットに割り当てられたローカルアドレスを取得する。
- f setsockopt — ソケットオプションの値を設定する。