次の方法で共有


宛先からのソケットの切断

Winsock Kernel (WSK) アプリケーションは、確立したソケット接続を経由したデータの送受信を完了すると、接続先のリモート トランスポート アドレスからコネクション指向のソケットを切断できます。 WSK アプリケーションは、WskDisconnect 関数を呼び出して、リモート トランスポート アドレスからソケットを切断します。 WSK アプリケーションは、打切り切断またはソケットの正常な切断を実行できます。 打切り切断と正常な切断の違いの詳細については、WskDisconnect を参照してください。

次のコード例は、WSK アプリケーションがリモート トランスポート アドレスからコネクション指向ソケットを正常に切断する方法を示しています。

// Prototype for the disconnect IoCompletion routine
NTSTATUS
  DisconnectComplete(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
    );

// Function to disconnect a socket from a remote transport address
NTSTATUS
  DisconnectSocket(
    PWSK_SOCKET Socket
    )
{
  PWSK_PROVIDER_CONNECTION_DISPATCH Dispatch;
  PIRP Irp;
  NTSTATUS Status;
 
  // Get pointer to the socket's provider dispatch structure
  Dispatch =
    (PWSK_PROVIDER_CONNECTION_DISPATCH)(Socket->Dispatch);

  // Allocate an IRP
  Irp =
    IoAllocateIrp(
      1,
      FALSE
      );

  // Check result
  if (!Irp)
  {
    // Return error
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  // Set the completion routine for the IRP
  IoSetCompletionRoutine(
    Irp,
    DisconnectComplete,
    Socket,  // Use the socket object for the context
    TRUE,
    TRUE,
    TRUE
    );

  // Initiate the disconnect operation on the socket
  Status =
    Dispatch->WskDisconnect(
      Socket,
      NULL,  // No final data to be transmitted
      0,     // No flags (graceful disconnect)
      Irp
      );

  // Return the status of the call to WskDisconnect()
  return Status;
}

// Disconnect IoCompletion routine
NTSTATUS
  DisconnectComplete(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
    )
{
  UNREFERENCED_PARAMETER(DeviceObject);

  PWSK_SOCKET Socket;

  // Check the result of the disconnect operation
  if (Irp->IoStatus.Status == STATUS_SUCCESS)
  {
    // Get the socket object from the context
    Socket = (PWSK_SOCKET)Context;

    // Perform the next operation on the socket
    ...
  }

  // Error status
  else
  {
    // Handle error
    ...
  }

  // Free the IRP
  IoFreeIrp(Irp);

  // Always return STATUS_MORE_PROCESSING_REQUIRED to
  // terminate the completion processing of the IRP.
  return STATUS_MORE_PROCESSING_REQUIRED;
}

WSK アプリケーションがソケットの正常な切断を行う場合、wskDisconnect 関数にWSK_BUF構造体へのポインターを渡すことで、ソケットが切断される前に、データの最終的なバッファーをリモート トランスポート アドレスに送信できます。

WSK アプリケーションが、最初に接続先のリモート トランスポート アドレスからソケットを切断せずにコネクション指向ソケットを閉じる場合、WSK サブシステムはソケットを閉じる前にソケットの打切り切断を自動的に行います。 ソケットを閉じる方法の詳細は、「ソケットを閉じる」を参照してください。