WSAConnectByNameW
関数シグネチャ
// WS2_32.dll (Unicode / -W)
#include <windows.h>
BOOL WSAConnectByNameW(
SOCKET s,
LPWSTR nodename,
LPWSTR servicename,
DWORD* LocalAddressLength, // optional
SOCKADDR* LocalAddress, // optional
DWORD* RemoteAddressLength, // optional
SOCKADDR* RemoteAddress, // optional
const TIMEVAL* timeout, // optional
OVERLAPPED* Reserved // optional
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| s | SOCKET | in | 未接続のソケットを識別するディスクリプタ。 Note Windows 7、Windows Server 2008 R2 以前では、WSAConnectByName 関数はバインドされていない未接続のソケットを必要とします。これは接続を確立する他の Winsock 呼び出し(たとえば WSAConnect)とは異なります。
|
| nodename | LPWSTR | in | IPv4 または IPv6 で接続先となるホストの名前、またはホストの IP アドレスを格納する NULL 終端文字列。 |
| servicename | LPWSTR | in | IPv4 または IPv6 で接続先となるホストのサービス名または宛先ポートを格納する NULL 終端文字列。 サービス名はポート番号に対する文字列のエイリアスです。たとえば “http” はポート 80 のエイリアスで、HTTP プロトコルで Web サーバが使用する既定のポートとして Internet Engineering Task Force (IETF) によって定義されています。ポート番号を指定しない場合に servicename パラメータに指定できる値は、次のファイルに記載されています。
|
| 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 | 呼び出しを中止する前に、リモートアプリケーションからの応答を待機する時間(ミリ秒単位)。 |
| Reserved | OVERLAPPED* | optional | 将来の実装のために予約されています。このパラメータは NULL に設定する必要があります。 |
戻り値の型: BOOL
公式ドキュメント
指定したホストおよびポートへの接続を確立します。(Unicode)
戻り値
接続が確立された場合、WSAConnectByName は TRUE を返し、呼び出し側がバッファを提供していれば LocalAddress および RemoteAddress パラメータが設定されます。
呼び出しが失敗した場合は FALSE が返されます。続いて WSAGetLastError を呼び出すことで、拡張エラー情報を取得できます。
| 戻り値 | 説明 |
|---|---|
|
nodename パラメータとして渡されたホストに到達できませんでした。 |
|
無効なパラメータが関数に渡されました。nodename または servicename パラメータは NULL であってはなりません。Reserved パラメータは NULL でなければなりません。 |
|
十分なメモリを割り当てることができませんでした。 |
|
無効なソケットが関数に渡されました。s パラメータは INVALID_SOCKET または NULL であってはなりません。 |
|
timeout パラメータを超過する前に、リモートアプリケーションからの応答を受信できませんでした。 |
解説(Remarks)
WSAConnectByName は、特定のポート上のリモートホストへの迅速で透過的な接続を可能にするために提供されています。IPv6 版と IPv4 版の両方に対応しています。
IPv6 と IPv4 の両方の通信を有効にするには、次の方法を使用します。
- WSAConnectByName を呼び出す前に、IPV6_V6ONLY ソケットオプションを無効にするため、AF_INET6 アドレスファミリ用に作成されたソケットに対して setsockopt 関数を呼び出す必要があります。これは、ソケットに対して setsockopt 関数を呼び出し、level パラメータを IPPROTO_IPV6(IPPROTO_IPV6 Socket Options を参照)、optname パラメータを IPV6_V6ONLY、optvalue パラメータの値を 0 に設定することで実現します。
WSAConnectByName には次の制限があります。 SOCK_STREAM 型のような、コネクション指向のソケットに対してのみ動作します。 この関数はオーバーラップ I/O や非ブロッキング動作をサポートしません。WSAConnectByName は、ソケットが非ブロッキングモードであってもブロックします。
WSAConnectByName は、接続確立時のユーザ提供データをサポートしません。この呼び出しは FLOWSPEC 構造体もサポートしません。これらの機能が必要な場合は、代わりに WSAConnect を使用する必要があります。
Windows 10 より前のバージョンでは、WSAConnectByName の socket パラメータはバインドされていないソケットでなければならないため、アプリケーションが特定のローカルアドレスまたはポートにバインドする必要がある場合は WSAConnectByName を使用できません。
この制限は Windows 10 で撤廃されました。
RemoteAddress および LocalAddress パラメータは、汎用的なデータ型である SOCKADDR 構造体を指します。WSAConnectByName が呼び出される際には、これらのパラメータには実際に使用されるネットワークプロトコルまたはアドレスファミリ固有のソケットアドレス型が渡されることが想定されています。したがって IPv4 アドレスの場合は、RemoteAddress および LocalAddress パラメータとして、sockaddr_in 構造体へのポインタを SOCKADDR へのポインタにキャストします。IPv6 アドレスの場合は、RemoteAddress および LocalAddress パラメータとして、sockaddr_in6 構造体へのポインタを SOCKADDR へのポインタにキャストします。
WSAConnectByName 関数が 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: WSAConnectByNameW 関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストアアプリでサポートされています。
Examples
WSAConnectByName を使用して接続を確立します。
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <mswsock.h> // Need for SO_UPDATE_CONNECT_CONTEXT
#include <stdio.h>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
SOCKET
OpenAndConnect(LPWSTR NodeName, LPWSTR PortName)
{
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){
wprintf(L"socket failed with error: %d\n", WSAGetLastError());
return INVALID_SOCKET;
}
iResult = setsockopt(ConnSocket, IPPROTO_IPV6,
IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
if (iResult == SOCKET_ERROR){
wprintf(L"setsockopt for IPV6_V6ONLY failed with error: %d\n",
WSAGetLastError());
closesocket(ConnSocket);
return INVALID_SOCKET;
}
bSuccess = WSAConnectByName(ConnSocket, NodeName,
PortName, &dwLocalAddr,
(SOCKADDR*)&LocalAddr,
&dwRemoteAddr,
(SOCKADDR*)&RemoteAddr,
NULL,
NULL);
if (!bSuccess){
wprintf(L"WsaConnectByName failed with error: %d\n", WSAGetLastError());
closesocket(ConnSocket);
return INVALID_SOCKET;
}
iResult = setsockopt(ConnSocket, SOL_SOCKET,
SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
if (iResult == SOCKET_ERROR){
wprintf(L"setsockopt for SO_UPDATE_CONNECT_CONTEXT failed with error: %d\n",
WSAGetLastError());
closesocket(ConnSocket);
return INVALID_SOCKET;
}
return ConnSocket;
}
int __cdecl wmain(int argc, wchar_t **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
SOCKET s = INVALID_SOCKET;
// Validate the parameters
if (argc != 3) {
wprintf(L"usage: %ws <Nodename> <Portname>\n", argv[0]);
wprintf(L"wsaconnectbyname establishes a connection to a specified host and port.\n");
wprintf(L"%ws www.contoso.com 8080\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
wprintf(L"WSAStartup failed: %d\n", iResult);
return 1;
}
wprintf(L"WsaConnectByName with following parameters:\n");
wprintf(L"\tNodename = %ws\n", argv[1]);
wprintf(L"\tPortname (or port) = %ws\n\n", argv[2]);
//--------------------------------
// Call our function that uses the WsaConnectByName.
s = OpenAndConnect(argv[1], argv[2]);
if ( s == INVALID_SOCKET ) {
wprintf(L"WsaConnectByName failed with error: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
else
{
wprintf(L"WsaConnectByName succeeded\n");
closesocket(s);
WSACleanup();
return 0;
}
}
winsock2.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいてこの関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして WSAConnectByName を定義しています。エンコーディング中立なエイリアスの使用と、エンコーディング中立でないコードを混在させると、コンパイルエラーや実行時エラーを引き起こす不一致につながる可能性があります。詳細については、Conventions for Function Prototypes を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// WS2_32.dll (Unicode / -W)
#include <windows.h>
BOOL WSAConnectByNameW(
SOCKET s,
LPWSTR nodename,
LPWSTR servicename,
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", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
static extern bool WSAConnectByNameW(
UIntPtr s, // SOCKET
[MarshalAs(UnmanagedType.LPWStr)] string nodename, // LPWSTR
[MarshalAs(UnmanagedType.LPWStr)] string servicename, // LPWSTR
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", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSAConnectByNameW(
s As UIntPtr, ' SOCKET
<MarshalAs(UnmanagedType.LPWStr)> nodename As String, ' LPWSTR
<MarshalAs(UnmanagedType.LPWStr)> servicename As String, ' LPWSTR
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
' nodename : LPWSTR
' servicename : LPWSTR
' 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 WSAConnectByNameW Lib "ws2_32" ( _
ByVal s As LongPtr, _
ByVal nodename As LongPtr, _
ByVal servicename 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
' 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
WSAConnectByNameW = ctypes.windll.ws2_32.WSAConnectByNameW
WSAConnectByNameW.restype = wintypes.BOOL
WSAConnectByNameW.argtypes = [
ctypes.c_size_t, # s : SOCKET
wintypes.LPCWSTR, # nodename : LPWSTR
wintypes.LPCWSTR, # servicename : LPWSTR
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')
WSAConnectByNameW = Fiddle::Function.new(
lib['WSAConnectByNameW'],
[
Fiddle::TYPE_UINTPTR_T, # s : SOCKET
Fiddle::TYPE_VOIDP, # nodename : LPWSTR
Fiddle::TYPE_VOIDP, # servicename : LPWSTR
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)
# Wide strings: pass str.encode("UTF-16LE") + "\x00\x00"#[link(name = "ws2_32")]
extern "system" {
fn WSAConnectByNameW(
s: usize, // SOCKET
nodename: *mut u16, // LPWSTR
servicename: *mut u16, // LPWSTR
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", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool WSAConnectByNameW(UIntPtr s, [MarshalAs(UnmanagedType.LPWStr)] string nodename, [MarshalAs(UnmanagedType.LPWStr)] string servicename, IntPtr LocalAddressLength, IntPtr LocalAddress, IntPtr RemoteAddressLength, IntPtr RemoteAddress, IntPtr timeout, IntPtr Reserved);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSAConnectByNameW' -Namespace Win32 -PassThru
# $api::WSAConnectByNameW(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)#uselib "WS2_32.dll"
#func global WSAConnectByNameW "WSAConnectByNameW" wptr, wptr, wptr, wptr, wptr, wptr, wptr, wptr, wptr
; WSAConnectByNameW s, nodename, servicename, varptr(LocalAddressLength), varptr(LocalAddress), varptr(RemoteAddressLength), varptr(RemoteAddress), varptr(timeout), varptr(Reserved) ; 戻り値は stat
; s : SOCKET -> "wptr"
; nodename : LPWSTR -> "wptr"
; servicename : LPWSTR -> "wptr"
; LocalAddressLength : DWORD* optional, in/out -> "wptr"
; LocalAddress : SOCKADDR* optional, out -> "wptr"
; RemoteAddressLength : DWORD* optional, in/out -> "wptr"
; RemoteAddress : SOCKADDR* optional, out -> "wptr"
; timeout : TIMEVAL* optional -> "wptr"
; Reserved : OVERLAPPED* optional -> "wptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "WS2_32.dll" #cfunc global WSAConnectByNameW "WSAConnectByNameW" sptr, wstr, wstr, var, var, var, var, var, var ; res = WSAConnectByNameW(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved) ; s : SOCKET -> "sptr" ; nodename : LPWSTR -> "wstr" ; servicename : LPWSTR -> "wstr" ; 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 WSAConnectByNameW "WSAConnectByNameW" sptr, wstr, wstr, sptr, sptr, sptr, sptr, sptr, sptr ; res = WSAConnectByNameW(s, nodename, servicename, varptr(LocalAddressLength), varptr(LocalAddress), varptr(RemoteAddressLength), varptr(RemoteAddress), varptr(timeout), varptr(Reserved)) ; s : SOCKET -> "sptr" ; nodename : LPWSTR -> "wstr" ; servicename : LPWSTR -> "wstr" ; 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 WSAConnectByNameW(SOCKET s, LPWSTR nodename, LPWSTR servicename, DWORD* LocalAddressLength, SOCKADDR* LocalAddress, DWORD* RemoteAddressLength, SOCKADDR* RemoteAddress, TIMEVAL* timeout, OVERLAPPED* Reserved) #uselib "WS2_32.dll" #cfunc global WSAConnectByNameW "WSAConnectByNameW" intptr, wstr, wstr, var, var, var, var, var, var ; res = WSAConnectByNameW(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved) ; s : SOCKET -> "intptr" ; nodename : LPWSTR -> "wstr" ; servicename : LPWSTR -> "wstr" ; 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 WSAConnectByNameW(SOCKET s, LPWSTR nodename, LPWSTR servicename, DWORD* LocalAddressLength, SOCKADDR* LocalAddress, DWORD* RemoteAddressLength, SOCKADDR* RemoteAddress, TIMEVAL* timeout, OVERLAPPED* Reserved) #uselib "WS2_32.dll" #cfunc global WSAConnectByNameW "WSAConnectByNameW" intptr, wstr, wstr, intptr, intptr, intptr, intptr, intptr, intptr ; res = WSAConnectByNameW(s, nodename, servicename, varptr(LocalAddressLength), varptr(LocalAddress), varptr(RemoteAddressLength), varptr(RemoteAddress), varptr(timeout), varptr(Reserved)) ; s : SOCKET -> "intptr" ; nodename : LPWSTR -> "wstr" ; servicename : LPWSTR -> "wstr" ; 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")
procWSAConnectByNameW = ws2_32.NewProc("WSAConnectByNameW")
)
// s (SOCKET), nodename (LPWSTR), servicename (LPWSTR), 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 := procWSAConnectByNameW.Call(
uintptr(s),
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(nodename))),
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(servicename))),
uintptr(LocalAddressLength),
uintptr(LocalAddress),
uintptr(RemoteAddressLength),
uintptr(RemoteAddress),
uintptr(timeout),
uintptr(Reserved),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // BOOLfunction WSAConnectByNameW(
s: NativeUInt; // SOCKET
nodename: PWideChar; // LPWSTR
servicename: PWideChar; // LPWSTR
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 'WSAConnectByNameW';result := DllCall("WS2_32\WSAConnectByNameW"
, "UPtr", s ; SOCKET
, "WStr", nodename ; LPWSTR
, "WStr", servicename ; LPWSTR
, "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●WSAConnectByNameW(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved) = DLL("WS2_32.dll", "bool WSAConnectByNameW(int, char*, char*, void*, void*, void*, void*, void*, void*)")
# 呼び出し: WSAConnectByNameW(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
# s : SOCKET -> "int"
# nodename : LPWSTR -> "char*"
# servicename : LPWSTR -> "char*"
# 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)。
# ※-W(Unicode)関数。なでしこ1はANSIのため -A 版の利用を推奨。const std = @import("std");
extern "ws2_32" fn WSAConnectByNameW(
s: usize, // SOCKET
nodename: [*c]const u16, // LPWSTR
servicename: [*c]const u16, // LPWSTR
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;
// Unicode(-W): UTF-16LE のヌル終端バッファ([*c]const u16)を渡す。proc WSAConnectByNameW(
s: uint, # SOCKET
nodename: WideCString, # LPWSTR
servicename: WideCString, # LPWSTR
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: "WSAConnectByNameW", stdcall, dynlib: "WS2_32.dll".}
# Unicode(-W): WideCString は newWideCString("...") で生成。pragma(lib, "ws2_32");
extern(Windows)
int WSAConnectByNameW(
size_t s, // SOCKET
const(wchar)* nodename, // LPWSTR
const(wchar)* servicename, // LPWSTR
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((:WSAConnectByNameW, "WS2_32.dll"), stdcall, Int32,
(Csize_t, Cwstring, Cwstring, Ptr{UInt32}, Ptr{SOCKADDR}, Ptr{UInt32}, Ptr{SOCKADDR}, Ptr{TIMEVAL}, Ptr{OVERLAPPED}),
s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
# s : SOCKET -> Csize_t
# nodename : LPWSTR -> Cwstring
# servicename : LPWSTR -> Cwstring
# 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 では無視)。
# Unicode(-W): Cwstring には transcode(UInt16, "...") 等で UTF-16 を渡す。local ffi = require("ffi")
ffi.cdef[[
int32_t WSAConnectByNameW(
uintptr_t s,
const uint16_t* nodename,
const uint16_t* servicename,
uint32_t* LocalAddressLength,
void* LocalAddress,
uint32_t* RemoteAddressLength,
void* RemoteAddress,
void* timeout,
void* Reserved);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSAConnectByNameW(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
-- s : SOCKET
-- nodename : LPWSTR
-- servicename : LPWSTR
-- 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 に追加すること。
-- Unicode(-W): uint16_t* には UTF-16LE のバッファ(ffi.new("uint16_t[?]", ...))を渡す。const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSAConnectByNameW = lib.func('__stdcall', 'WSAConnectByNameW', 'int32_t', ['uintptr_t', 'str16', 'str16', 'uint32_t *', 'void *', 'uint32_t *', 'void *', 'void *', 'void *']);
// WSAConnectByNameW(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
// s : SOCKET -> 'uintptr_t'
// nodename : LPWSTR -> 'str16'
// servicename : LPWSTR -> 'str16'
// 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", {
WSAConnectByNameW: { parameters: ["usize", "buffer", "buffer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer"], result: "i32" },
});
// lib.symbols.WSAConnectByNameW(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
// s : SOCKET -> "usize"
// nodename : LPWSTR -> "buffer"
// servicename : LPWSTR -> "buffer"
// 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"。Unicode(-W) は new TextEncoder() ではなく UTF-16LE のバイト列(末尾に \x00\x00)を Uint8Array で渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t WSAConnectByNameW(
size_t s,
const uint16_t* nodename,
const uint16_t* servicename,
uint32_t* LocalAddressLength,
void* LocalAddress,
uint32_t* RemoteAddressLength,
void* RemoteAddress,
void* timeout,
void* Reserved);
C, "WS2_32.dll");
// $ffi->WSAConnectByNameW(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved);
// s : SOCKET
// nodename : LPWSTR
// servicename : LPWSTR
// 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, W32APIOptions.UNICODE_OPTIONS);
boolean WSAConnectByNameW(
long s, // SOCKET
WString nodename, // LPWSTR
WString servicename, // LPWSTR
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
);
}
// Unicode(-W): WString(入力)/char[](出力)で UTF-16 をマーシャリング。@[Link("ws2_32")]
lib LibWS2_32
fun WSAConnectByNameW = WSAConnectByNameW(
s : LibC::SizeT, # SOCKET
nodename : UInt16*, # LPWSTR
servicename : UInt16*, # LPWSTR
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 WSAConnectByNameWNative = Int32 Function(UintPtr, Pointer<Utf16>, Pointer<Utf16>, Pointer<Uint32>, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
typedef WSAConnectByNameWDart = int Function(int, Pointer<Utf16>, Pointer<Utf16>, Pointer<Uint32>, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
final WSAConnectByNameW = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<WSAConnectByNameWNative, WSAConnectByNameWDart>('WSAConnectByNameW');
// s : SOCKET -> UintPtr
// nodename : LPWSTR -> Pointer<Utf16>
// servicename : LPWSTR -> Pointer<Utf16>
// 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 WSAConnectByNameW(
s: NativeUInt; // SOCKET
nodename: PWideChar; // LPWSTR
servicename: PWideChar; // LPWSTR
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 'WSAConnectByNameW';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "WSAConnectByNameW"
c_WSAConnectByNameW :: CUIntPtr -> CWString -> CWString -> Ptr Word32 -> Ptr () -> Ptr Word32 -> Ptr () -> Ptr () -> Ptr () -> IO CInt
-- s : SOCKET -> CUIntPtr
-- nodename : LPWSTR -> CWString
-- servicename : LPWSTR -> CWString
-- 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 wsaconnectbynamew =
foreign "WSAConnectByNameW"
(size_t @-> (ptr uint16_t) @-> (ptr uint16_t) @-> (ptr uint32_t) @-> (ptr void) @-> (ptr uint32_t) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> returning int32_t)
(* s : SOCKET -> size_t *)
(* nodename : LPWSTR -> (ptr uint16_t) *)
(* servicename : LPWSTR -> (ptr uint16_t) *)
(* 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 ("WSAConnectByNameW" wsaconnect-by-name-w :convention :stdcall) :int32
(s :uint64) ; SOCKET
(nodename (:string :encoding :utf-16le)) ; LPWSTR
(servicename (:string :encoding :utf-16le)) ; LPWSTR
(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 $WSAConnectByNameW = Win32::API::More->new('WS2_32',
'BOOL WSAConnectByNameW(WPARAM s, LPCWSTR nodename, LPCWSTR servicename, LPVOID LocalAddressLength, LPVOID LocalAddress, LPVOID RemoteAddressLength, LPVOID RemoteAddress, LPVOID timeout, LPVOID Reserved)');
# my $ret = $WSAConnectByNameW->Call($s, $nodename, $servicename, $LocalAddressLength, $LocalAddress, $RemoteAddressLength, $RemoteAddress, $timeout, $Reserved);
# s : SOCKET -> WPARAM
# nodename : LPWSTR -> LPCWSTR
# servicename : LPWSTR -> LPCWSTR
# 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 を使用。
# Unicode(-W): LPCWSTR/LPWSTR は Win32::API が UTF-16 変換を行う。関連項目
- f WSAConnectByNameA (ANSI版) — ホスト名とサービス名を指定して接続を確立する。
- f WSAConnect — 接続データやQoS指定付きで相手に接続する。
- f WSAConnectByList — アドレス候補一覧から接続可能な相手へ接続する。
- f WSAGetLastError — 直前のソケット操作のエラーコードを取得する。
- f getaddrinfo — ホスト名やサービス名からアドレス情報を解決する。
- f getpeername — 接続先ソケットのアドレス情報を取得する。
- f getsockname — ソケットに割り当てられたローカルアドレスを取得する。
- f setsockopt — ソケットオプションの値を設定する。