Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Когда приложение 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 выполняет корректное отключение сокета, оно может отправить завершающий буфер данных на удаленный транспортный адрес до отключения сокета, передав указатель на структуру WSK_BUF в функцию WskDisconnect.
Если приложение WSK закрывает cоединительный сокет, не отключив его принудительно от удаленного транспортного адреса, к которому он подключен, подсистема WSK автоматически выполняет принудительное отключение сокета перед его закрытием. Дополнительные сведения о закрытии сокета см. в разделе Закрытие сокета.