Erstellen von Sockets

Nachdem eine Winsock Kernel (WSK)-Anwendung erfolgreich an das WSK-Subsystem angefügt wurde, kann sie Sockets erstellen, die für Netzwerk-E/A-Vorgänge verwendet werden können. Eine WSK-Anwendung erstellt Sockets durch Aufrufen der WskSocket--Funktion. Auf die WskSocket--Funktion wird durch das WskSocket--Element der WSK_PROVIDER_DISPATCH-Struktur verwiesen, die vom WSK-Subsystem während der Anbindung zurückgegeben wurde.

Eine WSK-Anwendung muss angeben, welche Kategorie des WSK-Sockets erstellt wird, wenn ein neuer Socket erstellt wird. Weitere Informationen zu WSK-Socketkategorien finden Sie unter Winsock Kernel Socket Categories.

Eine WSK-Anwendung muss auch die Adressfamilie, den Sockettyp und das Protokoll angeben, wenn ein neuer Socket erstellt wird. Weitere Informationen zu den von WSK unterstützten Adressfamilien finden Sie unter WSK-Adressfamilien.

Beim Erstellen eines neuen Sockets muss eine WSK-Anwendung einen Socketkontextwert und einen Zeiger auf eine Client-Dispatch-Tabelle bereitstellen, falls die Anwendung Ereignisrückruffunktionen am Socket aktiviert. Weitere Informationen zum Aktivieren von Ereignisrückruffunktionen in einem Socket finden Sie unter Aktivieren und Deaktivieren von Ereignisrückruffunktionen.

Wenn der Socket erfolgreich erstellt wird, enthält das IoStatus.Information Feld des IRP einen Zeiger auf eine Socketobjektstruktur ( WSK_SOCKET) für den neuen Socket. Weitere Informationen zur Verwendung von IRPs mit WSK-Funktionen finden Sie unter Verwenden von IRPs mit Winsock-Kernel-Funktionen.

Das folgende Codebeispiel zeigt, wie eine WSK-Anwendung einen Überwachungssocket erstellen kann.

// Context structure for each socket
typedef struct _WSK_APP_SOCKET_CONTEXT {
  PWSK_SOCKET Socket;
  .
  .  // Other application-specific members
  .
} WSK_APP_SOCKET_CONTEXT, *PWSK_APP_SOCKET_CONTEXT;

// Prototype for the socket creation IoCompletion routine
NTSTATUS
  CreateListeningSocketComplete(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
    );

// Function to create a new listening socket
NTSTATUS
  CreateListeningSocket(
    PWSK_PROVIDER_NPI WskProviderNpi,
    PWSK_APP_SOCKET_CONTEXT SocketContext,
    PWSK_CLIENT_LISTEN_DISPATCH Dispatch,
    )
{
  PIRP Irp;
  NTSTATUS Status;

  // 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,
    CreateListeningSocketComplete,
    SocketContext,
    TRUE,
    TRUE,
    TRUE
    );

  // Initiate the creation of the socket
  Status =
    WskProviderNpi->Dispatch->
        WskSocket(
          WskProviderNpi->Client,
          AF_INET,
          SOCK_STREAM,
          IPPROTO_TCP,
          WSK_FLAG_LISTEN_SOCKET,
          SocketContext,
          Dispatch,
          NULL,
          NULL,
          NULL,
          Irp
          );

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

// Socket creation IoCompletion routine
NTSTATUS
  CreateListeningSocketComplete(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
    )
{
  UNREFERENCED_PARAMETER(DeviceObject);

  PWSK_APP_SOCKET_CONTEXT SocketContext;

  // Check the result of the socket creation
  if (Irp->IoStatus.Status == STATUS_SUCCESS)
  {
    // Get the pointer to the socket context
    SocketContext =
      (PWSK_APP_SOCKET_CONTEXT)Context;

    // Save the socket object for the new socket
    SocketContext->Socket =
      (PWSK_SOCKET)(Irp->IoStatus.Information);

    // Set any socket options for the new socket
    ...

    // Enable any event callback functions on the new socket
    ...

    // Perform any other initializations
    ...
  }

  // 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;
}

Für verbindungsorientierte Sockets kann eine WSK-Anwendung die WskSocketConnect--Funktion aufrufen, um einen Socket in einem einzigen Funktionsaufruf zu erstellen, zu binden und zu verbinden.