Win32 API 日本語リファレンス
ホームNetworking.WinSock › WSASendDisconnect

WSASendDisconnect

関数
切断時に相手へ終了データを送信する。
DLLWS2_32.dll呼出規約winapiSetLastErrorあり対応OSWindows 2000 以降

シグネチャ

// WS2_32.dll
#include <windows.h>

INT WSASendDisconnect(
    SOCKET s,
    WSABUF* lpOutboundDisconnectData   // optional
);

パラメーター

名前方向説明
sSOCKETinソケットを識別する記述子。
lpOutboundDisconnectDataWSABUF*inoptional送信する切断データへのポインター。

戻り値の型: INT

公式ドキュメント

WSASendDisconnect 関数は、ソケットの接続終了を開始し、切断データを送信します。

戻り値

エラーが発生しなかった場合、 WSASendDisconnect はゼロを返します。それ以外の場合は SOCKET_ERROR の値が返され、 WSAGetLastError を呼び出すことで特定のエラーコードを取得できます。

エラーコード 意味
WSANOTINITIALISED
この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。
WSAENETDOWN
ネットワークサブシステムが失敗しました。
WSAENOPROTOOPT
lpOutboundDisconnectData パラメーターが NULL ではなく、切断データがサービスプロバイダーでサポートされていません。
WSAEINPROGRESS
ブロッキング型の Windows Sockets 1.1 呼び出しが進行中であるか、サービスプロバイダーがコールバック関数をまだ処理中です。
WSAENOTCONN
ソケットが接続されていません(コネクション指向のソケットのみ)。
WSAENOTSOCK
記述子がソケットではありません。
WSAEFAULT
lpOutboundDisconnectData パラメーターの全体が、ユーザーアドレス空間の有効な部分に収まっていません。

解説(Remarks)

WSASendDisconnect 関数は、コネクション指向のソケットで使用され、送信を無効にし、切断データ(存在する場合)の送信とともに接続の終了を開始します。これは shutdown (SD_SEND) と同等ですが、 WSASendDisconnect は(それをサポートするプロトコルにおいて)切断データの送信も可能にする点が異なります。

この関数が正常に発行された後は、以降の送信は許可されません。

lpOutboundDisconnectData パラメーターは、NULL でない場合、リモート側が WSARecvDisconnect を使用して取得するために送信される、送信用の切断データを格納したバッファーを指します。

注意 Windows におけるネイティブの TCP/IP 実装は、切断データをサポートしていません。切断データは、その WSAPROTOCOL_INFO 構造体に XP1_DISCONNECT_DATA フラグを持つ Windows Sockets プロバイダーでのみサポートされます。インストールされているすべてのプロバイダーの WSAPROTOCOL_INFO 構造体を取得するには、 WSAEnumProtocols 関数を使用してください。
WSASendDisconnect 関数はソケットをクローズしません。また、ソケットに関連付けられたリソースは、 closesocket が呼び出されるまで解放されません。

WSASendDisconnect 関数は、ソケットの SO_LINGER 設定にかかわらずブロックしません。

アプリケーションは、WSASendDisconnect を呼び出した後にソケットを再利用できることを当てにすべきではありません。特に、Windows Sockets プロバイダーは、そのようなソケットに対する connect/WSAConnect の使用をサポートする必要はありません。

注意 WSASendDisconnect のようなブロッキング型の Winsock 呼び出しを発行する際、Winsock は呼び出しが完了する前にネットワークイベントを待機する必要がある場合があります。この状況では Winsock はアラート可能な待機を実行し、同じスレッドでスケジュールされた非同期プロシージャ呼び出し (APC) によって中断される可能性があります。同じスレッドで進行中のブロッキング型 Winsock 呼び出しを中断した APC の内部で、別のブロッキング型 Winsock 呼び出しを発行すると、未定義の動作を引き起こすため、Winsock クライアントは決してこれを試みてはなりません。
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// WS2_32.dll
#include <windows.h>

INT WSASendDisconnect(
    SOCKET s,
    WSABUF* lpOutboundDisconnectData   // optional
);
[DllImport("WS2_32.dll", SetLastError = true, ExactSpelling = true)]
static extern int WSASendDisconnect(
    UIntPtr s,   // SOCKET
    IntPtr lpOutboundDisconnectData   // WSABUF* optional
);
<DllImport("WS2_32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function WSASendDisconnect(
    s As UIntPtr,   ' SOCKET
    lpOutboundDisconnectData As IntPtr   ' WSABUF* optional
) As Integer
End Function
' s : SOCKET
' lpOutboundDisconnectData : WSABUF* optional
Declare PtrSafe Function WSASendDisconnect Lib "ws2_32" ( _
    ByVal s As LongPtr, _
    ByVal lpOutboundDisconnectData As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

WSASendDisconnect = ctypes.windll.ws2_32.WSASendDisconnect
WSASendDisconnect.restype = ctypes.c_int
WSASendDisconnect.argtypes = [
    ctypes.c_size_t,  # s : SOCKET
    ctypes.c_void_p,  # lpOutboundDisconnectData : WSABUF* optional
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WS2_32.dll')
WSASendDisconnect = Fiddle::Function.new(
  lib['WSASendDisconnect'],
  [
    Fiddle::TYPE_UINTPTR_T,  # s : SOCKET
    Fiddle::TYPE_VOIDP,  # lpOutboundDisconnectData : WSABUF* optional
  ],
  Fiddle::TYPE_INT)
#[link(name = "ws2_32")]
extern "system" {
    fn WSASendDisconnect(
        s: usize,  // SOCKET
        lpOutboundDisconnectData: *mut WSABUF  // WSABUF* optional
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("WS2_32.dll", SetLastError = true)]
public static extern int WSASendDisconnect(UIntPtr s, IntPtr lpOutboundDisconnectData);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WS2_32_WSASendDisconnect' -Namespace Win32 -PassThru
# $api::WSASendDisconnect(s, lpOutboundDisconnectData)
#uselib "WS2_32.dll"
#func global WSASendDisconnect "WSASendDisconnect" sptr, sptr
; WSASendDisconnect s, varptr(lpOutboundDisconnectData)   ; 戻り値は stat
; s : SOCKET -> "sptr"
; lpOutboundDisconnectData : WSABUF* optional -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WS2_32.dll"
#cfunc global WSASendDisconnect "WSASendDisconnect" sptr, var
; res = WSASendDisconnect(s, lpOutboundDisconnectData)
; s : SOCKET -> "sptr"
; lpOutboundDisconnectData : WSABUF* optional -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; INT WSASendDisconnect(SOCKET s, WSABUF* lpOutboundDisconnectData)
#uselib "WS2_32.dll"
#cfunc global WSASendDisconnect "WSASendDisconnect" intptr, var
; res = WSASendDisconnect(s, lpOutboundDisconnectData)
; s : SOCKET -> "intptr"
; lpOutboundDisconnectData : WSABUF* optional -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ws2_32 = windows.NewLazySystemDLL("WS2_32.dll")
	procWSASendDisconnect = ws2_32.NewProc("WSASendDisconnect")
)

// s (SOCKET), lpOutboundDisconnectData (WSABUF* optional)
r1, _, err := procWSASendDisconnect.Call(
	uintptr(s),
	uintptr(lpOutboundDisconnectData),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // INT
function WSASendDisconnect(
  s: NativeUInt;   // SOCKET
  lpOutboundDisconnectData: Pointer   // WSABUF* optional
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSASendDisconnect';
result := DllCall("WS2_32\WSASendDisconnect"
    , "UPtr", s   ; SOCKET
    , "Ptr", lpOutboundDisconnectData   ; WSABUF* optional
    , "Int")   ; return: INT
●WSASendDisconnect(s, lpOutboundDisconnectData) = DLL("WS2_32.dll", "int WSASendDisconnect(int, void*)")
# 呼び出し: WSASendDisconnect(s, lpOutboundDisconnectData)
# s : SOCKET -> "int"
# lpOutboundDisconnectData : WSABUF* optional -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "ws2_32" fn WSASendDisconnect(
    s: usize, // SOCKET
    lpOutboundDisconnectData: [*c]WSABUF // WSABUF* optional
) callconv(std.os.windows.WINAPI) i32;
proc WSASendDisconnect(
    s: uint,  # SOCKET
    lpOutboundDisconnectData: ptr WSABUF  # WSABUF* optional
): int32 {.importc: "WSASendDisconnect", stdcall, dynlib: "WS2_32.dll".}
pragma(lib, "ws2_32");
extern(Windows)
int WSASendDisconnect(
    size_t s,   // SOCKET
    WSABUF* lpOutboundDisconnectData   // WSABUF* optional
);
ccall((:WSASendDisconnect, "WS2_32.dll"), stdcall, Int32,
      (Csize_t, Ptr{WSABUF}),
      s, lpOutboundDisconnectData)
# s : SOCKET -> Csize_t
# lpOutboundDisconnectData : WSABUF* optional -> Ptr{WSABUF}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t WSASendDisconnect(
    uintptr_t s,
    void* lpOutboundDisconnectData);
]]
local ws2_32 = ffi.load("ws2_32")
-- ws2_32.WSASendDisconnect(s, lpOutboundDisconnectData)
-- s : SOCKET
-- lpOutboundDisconnectData : WSABUF* optional
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('WS2_32.dll');
const WSASendDisconnect = lib.func('__stdcall', 'WSASendDisconnect', 'int32_t', ['uintptr_t', 'void *']);
// WSASendDisconnect(s, lpOutboundDisconnectData)
// s : SOCKET -> 'uintptr_t'
// lpOutboundDisconnectData : WSABUF* optional -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("WS2_32.dll", {
  WSASendDisconnect: { parameters: ["usize", "pointer"], result: "i32" },
});
// lib.symbols.WSASendDisconnect(s, lpOutboundDisconnectData)
// s : SOCKET -> "usize"
// lpOutboundDisconnectData : WSABUF* optional -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t WSASendDisconnect(
    size_t s,
    void* lpOutboundDisconnectData);
C, "WS2_32.dll");
// $ffi->WSASendDisconnect(s, lpOutboundDisconnectData);
// s : SOCKET
// lpOutboundDisconnectData : WSABUF* 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);
    int WSASendDisconnect(
        long s,   // SOCKET
        Pointer lpOutboundDisconnectData   // WSABUF* optional
    );
}
@[Link("ws2_32")]
lib LibWS2_32
  fun WSASendDisconnect = WSASendDisconnect(
    s : LibC::SizeT,   # SOCKET
    lpOutboundDisconnectData : WSABUF*   # WSABUF* optional
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef WSASendDisconnectNative = Int32 Function(UintPtr, Pointer<Void>);
typedef WSASendDisconnectDart = int Function(int, Pointer<Void>);
final WSASendDisconnect = DynamicLibrary.open('WS2_32.dll')
    .lookupFunction<WSASendDisconnectNative, WSASendDisconnectDart>('WSASendDisconnect');
// s : SOCKET -> UintPtr
// lpOutboundDisconnectData : WSABUF* optional -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function WSASendDisconnect(
  s: NativeUInt;   // SOCKET
  lpOutboundDisconnectData: Pointer   // WSABUF* optional
): Integer; stdcall;
  external 'WS2_32.dll' name 'WSASendDisconnect';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "WSASendDisconnect"
  c_WSASendDisconnect :: CUIntPtr -> Ptr () -> IO Int32
-- s : SOCKET -> CUIntPtr
-- lpOutboundDisconnectData : WSABUF* optional -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wsasenddisconnect =
  foreign "WSASendDisconnect"
    (size_t @-> (ptr void) @-> returning int32_t)
(* s : SOCKET -> size_t *)
(* lpOutboundDisconnectData : WSABUF* 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 ("WSASendDisconnect" wsasend-disconnect :convention :stdcall) :int32
  (s :uint64)   ; SOCKET
  (lp-outbound-disconnect-data :pointer))   ; WSABUF* optional
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $WSASendDisconnect = Win32::API::More->new('WS2_32',
    'int WSASendDisconnect(WPARAM s, LPVOID lpOutboundDisconnectData)');
# my $ret = $WSASendDisconnect->Call($s, $lpOutboundDisconnectData);
# s : SOCKET -> WPARAM
# lpOutboundDisconnectData : WSABUF* optional -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目
使用する型