WSAConnectByNameA
関数シグネチャ
// WS2_32.dll (ANSI / -A)
#include <windows.h>
BOOL WSAConnectByNameA(
SOCKET s,
LPCSTR nodename,
LPCSTR servicename,
DWORD* LocalAddressLength, // optional
SOCKADDR* LocalAddress, // optional
DWORD* RemoteAddressLength, // optional
SOCKADDR* RemoteAddress, // optional
const TIMEVAL* timeout, // optional
OVERLAPPED* Reserved // optional
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| s | SOCKET | in | 未接続のソケットを識別するディスクリプタです。 注 Windows 7、Windows Server 2008 R2 以前では、WSAConnectByName 関数はバインドされておらず、かつ未接続のソケットを必要とします。これは接続を確立する他の Winsock 呼び出し(例: WSAConnect)とは異なります。
|
| nodename | LPCSTR | in | IPv4 または IPv6 で接続先となるホストの名前、またはホストの IP アドレスを含む NULL 終端文字列です。 |
| servicename | LPCSTR | in | IPv4 または IPv6 で接続先となるホストのサービス名、または宛先ポートを含む NULL 終端文字列です。 サービス名はポート番号に対する文字列のエイリアスです。たとえば「http」はポート 80 のエイリアスであり、これは Web サーバが HTTP プロトコルで使用する既定ポートとして 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
公式ドキュメント
指定されたホストおよびポートへの接続を確立します。(ANSI)
戻り値
接続が確立されると、WSAConnectByName は TRUE を返し、呼び出し側がバッファを提供していれば LocalAddress および RemoteAddress パラメータが設定されます。
呼び出しが失敗した場合は FALSE が返されます。その後 WSAGetLastError を呼び出すと、拡張エラー情報を取得できます。
| 戻り値 | 説明 |
|---|---|
|
nodename パラメータとして渡されたホストに到達できませんでした。 |
|
無効なパラメータが関数に渡されました。nodename パラメータまたは servicename パラメータは NULL であってはなりません。Reserved パラメータは NULL でなければなりません。 |
|
十分なメモリを割り当てられませんでした。 |
|
無効なソケットが関数に渡されました。s パラメータは INVALID_SOCKET または NULL であってはなりません。 |
|
timeout パラメータを超過する前に、リモートアプリケーションからの応答を受信できませんでした。 |
解説(Remarks)
WSAConnectByName は、特定のポート上のリモートホストへの迅速かつ透過的な接続を可能にするために提供されています。IPv6 と IPv4 の両バージョンに対応しています。
IPv6 と IPv4 の両方の通信を有効にするには、次の方法を使用します。
- WSAConnectByName を呼び出す前に、AF_INET6 アドレスファミリ用に作成したソケットに対して setsockopt 関数を呼び出し、IPV6_V6ONLY ソケットオプションを無効にする必要があります。これは、ソケットに対して setsockopt 関数を呼び出し、level パラメータを IPPROTO_IPV6(IPPROTO_IPV6 Socket Options を参照)に、optname パラメータを IPV6_V6ONLY に、optvalue パラメータの値をゼロに設定することで実現できます。
WSAConnectByName には次の制限があります。 この関数は、SOCK_STREAM 型のような、コネクション指向のソケットでのみ動作します。 この関数はオーバーラップ I/O やノンブロッキング動作をサポートしません。WSAConnectByName は、ソケットがノンブロッキングモードであってもブロックします。
WSAConnectByName は、接続確立時にユーザが指定するデータをサポートしません。また、この呼び出しは FLOWSPEC 構造体もサポートしません。これらの機能が必要な場合は、代わりに WSAConnect を使用する必要があります。
Windows 10 より前のバージョンでは、アプリケーションが特定のローカルアドレスまたはポートにバインドする必要がある場合、WSAConnectByName は使用できません。WSAConnectByName の socket パラメータはバインドされていないソケットでなければならないためです。
この制限は Windows 10 で撤廃されました。
RemoteAddress および LocalAddress パラメータは、汎用のデータ型である SOCKADDR 構造体を指します。WSAConnectByName を呼び出す際には、実際には使用するネットワークプロトコルまたはアドレスファミリに固有のソケットアドレス型がこれらのパラメータに渡されることが想定されています。したがって IPv4 アドレスの場合、sockaddr_in 構造体へのポインタを SOCKADDR へのポインタにキャストして RemoteAddress および LocalAddress パラメータとして渡します。IPv6 アドレスの場合は、sockaddr_in6 構造体へのポインタを SOCKADDR へのポインタにキャストして RemoteAddress および LocalAddress パラメータとして渡します。
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 ストアアプリでサポートされています。
例
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 (ANSI / -A)
#include <windows.h>
BOOL WSAConnectByNameA(
SOCKET s,
LPCSTR nodename,
LPCSTR 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.Ansi, SetLastError = true, ExactSpelling = true)]
static extern bool WSAConnectByNameA(
UIntPtr s, // SOCKET
[MarshalAs(UnmanagedType.LPStr)] string nodename, // LPCSTR
[MarshalAs(UnmanagedType.LPStr)] string servicename, // LPCSTR
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.Ansi, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSAConnectByNameA(
s As UIntPtr, ' SOCKET
<MarshalAs(UnmanagedType.LPStr)> nodename As String, ' LPCSTR
<MarshalAs(UnmanagedType.LPStr)> servicename As String, ' LPCSTR
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 : LPCSTR
' servicename : LPCSTR
' 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 WSAConnectByNameA Lib "ws2_32" ( _
ByVal s As LongPtr, _
ByVal nodename As String, _
ByVal servicename As String, _
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
WSAConnectByNameA = ctypes.windll.ws2_32.WSAConnectByNameA
WSAConnectByNameA.restype = wintypes.BOOL
WSAConnectByNameA.argtypes = [
ctypes.c_size_t, # s : SOCKET
wintypes.LPCSTR, # nodename : LPCSTR
wintypes.LPCSTR, # servicename : LPCSTR
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')
WSAConnectByNameA = Fiddle::Function.new(
lib['WSAConnectByNameA'],
[
Fiddle::TYPE_UINTPTR_T, # s : SOCKET
Fiddle::TYPE_VOIDP, # nodename : LPCSTR
Fiddle::TYPE_VOIDP, # servicename : LPCSTR
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 WSAConnectByNameA(
s: usize, // SOCKET
nodename: *const u8, // LPCSTR
servicename: *const u8, // LPCSTR
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.Ansi, SetLastError = true)]
public static extern bool WSAConnectByNameA(UIntPtr s, [MarshalAs(UnmanagedType.LPStr)] string nodename, [MarshalAs(UnmanagedType.LPStr)] string servicename, IntPtr LocalAddressLength, IntPtr LocalAddress, IntPtr RemoteAddressLength, IntPtr RemoteAddress, IntPtr timeout, IntPtr Reserved);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSAConnectByNameA' -Namespace Win32 -PassThru
# $api::WSAConnectByNameA(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)#uselib "WS2_32.dll"
#func global WSAConnectByNameA "WSAConnectByNameA" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr
; WSAConnectByNameA s, nodename, servicename, varptr(LocalAddressLength), varptr(LocalAddress), varptr(RemoteAddressLength), varptr(RemoteAddress), varptr(timeout), varptr(Reserved) ; 戻り値は stat
; s : SOCKET -> "sptr"
; nodename : LPCSTR -> "sptr"
; servicename : LPCSTR -> "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 WSAConnectByNameA "WSAConnectByNameA" sptr, str, str, var, var, var, var, var, var ; res = WSAConnectByNameA(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved) ; s : SOCKET -> "sptr" ; nodename : LPCSTR -> "str" ; servicename : LPCSTR -> "str" ; 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 WSAConnectByNameA "WSAConnectByNameA" sptr, str, str, sptr, sptr, sptr, sptr, sptr, sptr ; res = WSAConnectByNameA(s, nodename, servicename, varptr(LocalAddressLength), varptr(LocalAddress), varptr(RemoteAddressLength), varptr(RemoteAddress), varptr(timeout), varptr(Reserved)) ; s : SOCKET -> "sptr" ; nodename : LPCSTR -> "str" ; servicename : LPCSTR -> "str" ; 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 WSAConnectByNameA(SOCKET s, LPCSTR nodename, LPCSTR servicename, DWORD* LocalAddressLength, SOCKADDR* LocalAddress, DWORD* RemoteAddressLength, SOCKADDR* RemoteAddress, TIMEVAL* timeout, OVERLAPPED* Reserved) #uselib "WS2_32.dll" #cfunc global WSAConnectByNameA "WSAConnectByNameA" intptr, str, str, var, var, var, var, var, var ; res = WSAConnectByNameA(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved) ; s : SOCKET -> "intptr" ; nodename : LPCSTR -> "str" ; servicename : LPCSTR -> "str" ; 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 WSAConnectByNameA(SOCKET s, LPCSTR nodename, LPCSTR servicename, DWORD* LocalAddressLength, SOCKADDR* LocalAddress, DWORD* RemoteAddressLength, SOCKADDR* RemoteAddress, TIMEVAL* timeout, OVERLAPPED* Reserved) #uselib "WS2_32.dll" #cfunc global WSAConnectByNameA "WSAConnectByNameA" intptr, str, str, intptr, intptr, intptr, intptr, intptr, intptr ; res = WSAConnectByNameA(s, nodename, servicename, varptr(LocalAddressLength), varptr(LocalAddress), varptr(RemoteAddressLength), varptr(RemoteAddress), varptr(timeout), varptr(Reserved)) ; s : SOCKET -> "intptr" ; nodename : LPCSTR -> "str" ; servicename : LPCSTR -> "str" ; 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")
procWSAConnectByNameA = ws2_32.NewProc("WSAConnectByNameA")
)
// s (SOCKET), nodename (LPCSTR), servicename (LPCSTR), 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 := procWSAConnectByNameA.Call(
uintptr(s),
uintptr(unsafe.Pointer(windows.BytePtrFromString(nodename))),
uintptr(unsafe.Pointer(windows.BytePtrFromString(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 WSAConnectByNameA(
s: NativeUInt; // SOCKET
nodename: PAnsiChar; // LPCSTR
servicename: PAnsiChar; // LPCSTR
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 'WSAConnectByNameA';result := DllCall("WS2_32\WSAConnectByNameA"
, "UPtr", s ; SOCKET
, "AStr", nodename ; LPCSTR
, "AStr", servicename ; LPCSTR
, "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●WSAConnectByNameA(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved) = DLL("WS2_32.dll", "bool WSAConnectByNameA(int, char*, char*, void*, void*, void*, void*, void*, void*)")
# 呼び出し: WSAConnectByNameA(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
# s : SOCKET -> "int"
# nodename : LPCSTR -> "char*"
# servicename : LPCSTR -> "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)。const std = @import("std");
extern "ws2_32" fn WSAConnectByNameA(
s: usize, // SOCKET
nodename: [*c]const u8, // LPCSTR
servicename: [*c]const u8, // LPCSTR
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 WSAConnectByNameA(
s: uint, # SOCKET
nodename: cstring, # LPCSTR
servicename: cstring, # LPCSTR
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: "WSAConnectByNameA", stdcall, dynlib: "WS2_32.dll".}pragma(lib, "ws2_32");
extern(Windows)
int WSAConnectByNameA(
size_t s, // SOCKET
const(char)* nodename, // LPCSTR
const(char)* servicename, // LPCSTR
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((:WSAConnectByNameA, "WS2_32.dll"), stdcall, Int32,
(Csize_t, Cstring, Cstring, 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 : LPCSTR -> Cstring
# servicename : LPCSTR -> Cstring
# 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 WSAConnectByNameA(
uintptr_t s,
const char* nodename,
const char* servicename,
uint32_t* LocalAddressLength,
void* LocalAddress,
uint32_t* RemoteAddressLength,
void* RemoteAddress,
void* timeout,
void* Reserved);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSAConnectByNameA(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
-- s : SOCKET
-- nodename : LPCSTR
-- servicename : LPCSTR
-- 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 WSAConnectByNameA = lib.func('__stdcall', 'WSAConnectByNameA', 'int32_t', ['uintptr_t', 'str', 'str', 'uint32_t *', 'void *', 'uint32_t *', 'void *', 'void *', 'void *']);
// WSAConnectByNameA(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
// s : SOCKET -> 'uintptr_t'
// nodename : LPCSTR -> 'str'
// servicename : LPCSTR -> 'str'
// 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", {
WSAConnectByNameA: { parameters: ["usize", "buffer", "buffer", "pointer", "pointer", "pointer", "pointer", "pointer", "pointer"], result: "i32" },
});
// lib.symbols.WSAConnectByNameA(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved)
// s : SOCKET -> "usize"
// nodename : LPCSTR -> "buffer"
// servicename : LPCSTR -> "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"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t WSAConnectByNameA(
size_t s,
const char* nodename,
const char* servicename,
uint32_t* LocalAddressLength,
void* LocalAddress,
uint32_t* RemoteAddressLength,
void* RemoteAddress,
void* timeout,
void* Reserved);
C, "WS2_32.dll");
// $ffi->WSAConnectByNameA(s, nodename, servicename, LocalAddressLength, LocalAddress, RemoteAddressLength, RemoteAddress, timeout, Reserved);
// s : SOCKET
// nodename : LPCSTR
// servicename : LPCSTR
// 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.ASCII_OPTIONS);
boolean WSAConnectByNameA(
long s, // SOCKET
String nodename, // LPCSTR
String servicename, // LPCSTR
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 WSAConnectByNameA = WSAConnectByNameA(
s : LibC::SizeT, # SOCKET
nodename : UInt8*, # LPCSTR
servicename : UInt8*, # LPCSTR
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 WSAConnectByNameANative = Int32 Function(UintPtr, Pointer<Utf8>, Pointer<Utf8>, Pointer<Uint32>, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
typedef WSAConnectByNameADart = int Function(int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Uint32>, Pointer<Void>, Pointer<Uint32>, Pointer<Void>, Pointer<Void>, Pointer<Void>);
final WSAConnectByNameA = DynamicLibrary.open('WS2_32.dll')
.lookupFunction<WSAConnectByNameANative, WSAConnectByNameADart>('WSAConnectByNameA');
// s : SOCKET -> UintPtr
// nodename : LPCSTR -> Pointer<Utf8>
// servicename : LPCSTR -> Pointer<Utf8>
// 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 WSAConnectByNameA(
s: NativeUInt; // SOCKET
nodename: PAnsiChar; // LPCSTR
servicename: PAnsiChar; // LPCSTR
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 'WSAConnectByNameA';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "WSAConnectByNameA"
c_WSAConnectByNameA :: CUIntPtr -> CString -> CString -> Ptr Word32 -> Ptr () -> Ptr Word32 -> Ptr () -> Ptr () -> Ptr () -> IO CInt
-- s : SOCKET -> CUIntPtr
-- nodename : LPCSTR -> CString
-- servicename : LPCSTR -> CString
-- 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 wsaconnectbynamea =
foreign "WSAConnectByNameA"
(size_t @-> string @-> string @-> (ptr uint32_t) @-> (ptr void) @-> (ptr uint32_t) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> returning int32_t)
(* s : SOCKET -> size_t *)
(* nodename : LPCSTR -> string *)
(* servicename : LPCSTR -> string *)
(* 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 ("WSAConnectByNameA" wsaconnect-by-name-a :convention :stdcall) :int32
(s :uint64) ; SOCKET
(nodename :string) ; LPCSTR
(servicename :string) ; LPCSTR
(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 $WSAConnectByNameA = Win32::API::More->new('WS2_32',
'BOOL WSAConnectByNameA(WPARAM s, LPCSTR nodename, LPCSTR servicename, LPVOID LocalAddressLength, LPVOID LocalAddress, LPVOID RemoteAddressLength, LPVOID RemoteAddress, LPVOID timeout, LPVOID Reserved)');
# my $ret = $WSAConnectByNameA->Call($s, $nodename, $servicename, $LocalAddressLength, $LocalAddress, $RemoteAddressLength, $RemoteAddress, $timeout, $Reserved);
# s : SOCKET -> WPARAM
# nodename : LPCSTR -> LPCSTR
# servicename : LPCSTR -> LPCSTR
# 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 を使用。関連項目
- f WSAConnectByNameW (Unicode版) — ホスト名とサービス名を指定して接続を確立する。
- f WSAConnect — 接続データやQoS指定付きで相手に接続する。
- f WSAConnectByList — アドレス候補一覧から接続可能な相手へ接続する。
- f WSAGetLastError — 直前のソケット操作のエラーコードを取得する。
- f getaddrinfo — ホスト名やサービス名からアドレス情報を解決する。
- f getpeername — 接続先ソケットのアドレス情報を取得する。
- f getsockname — ソケットに割り当てられたローカルアドレスを取得する。
- f setsockopt — ソケットオプションの値を設定する。