다음을 통해 공유


Connection-Oriented 소켓을 통해 데이터 수신

WSK(Winsock Kernel) 애플리케이션이 연결 지향 소켓을 원격 전송 주소에 연결한 후 소켓을 통해 데이터를 수신할 수 있습니다. WSK 애플리케이션은 수신 대기 소켓에서 수락한 연결 지향 소켓을 통해 데이터를 수신할 수도 있습니다. WSK 애플리케이션은 WskReceive 함수를 호출하여 연결 지향 소켓을 통해 데이터를 받습니다.

다음 코드 예제에서는 WSK 애플리케이션 연결 지향 소켓을 통해 데이터를 받을 수 있는 방법을 보여 줍니다.

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

// Function to receive data
NTSTATUS
  ReceiveData(
    PWSK_SOCKET Socket,
    PWSK_BUF DataBuffer
    )
{
  PWSK_PROVIDER_CONNECTION_DISPATCH Dispatch;
  PIRP Irp;
  NTSTATUS Status;

  // Get pointer to the 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,
    ReceiveComplete,
    DataBuffer,  // Use the data buffer for the context
    TRUE,
    TRUE,
    TRUE
    );

  // Initiate the receive operation on the socket
  Status =
    Dispatch->WskReceive(
      Socket,
      DataBuffer,
      0,  // No flags are specified
      Irp
      );

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

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

  PWSK_BUF DataBuffer;
  ULONG ByteCount;

  // Check the result of the receive operation
  if (Irp->IoStatus.Status == STATUS_SUCCESS)
  {
    // Get the pointer to the data buffer
    DataBuffer = (PWSK_BUF)Context;
 
    // Get the number of bytes received
    ByteCount = (ULONG)(Irp->IoStatus.Information);

    // Process the received data
    ...
  }

  // 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 애플리케이션은 WskReceive 함수를 호출하여 연결 지향 소켓을 통해 데이터를 수신하는 대신 소켓에서 WskReceiveEvent 이벤트 콜백 함수를 사용하도록 설정할 수 있습니다. WSK 애플리케이션이 연결 지향 소켓에서 WskReceiveEvent 이벤트 콜백 함수를 사용하도록 설정하는 경우 WSK 하위 시스템은 소켓에서 새 데이터를 받을 때마다 소켓의 WskReceiveEvent 이벤트 콜백 함수를 호출합니다. 연결 지향 소켓의 WskReceiveEvent 이벤트 콜백 함수를 사용하도록 설정하는 방법에 대한 자세한 내용은 이벤트 콜백 함수 사용 및 비활성화를 참조하세요.

다음 코드 예제에서는 WSK 애플리케이션 연결 지향 소켓의 WskReceiveEvent 이벤트 콜백 함수를 호출 하는 WSK 하위 시스템에 의해 데이터를 받을 수 있는 방법을 보여 줍니다.

// A connection-oriented socket's WskReceiveEvent
// event callback function
NTSTATUS WSKAPI
  WskReceiveEvent(
    PVOID SocketContext,
    ULONG Flags,
    PWSK_DATA_INDICATION DataIndication,
    SIZE_T BytesIndicated,
    SIZE_T *BytesAccepted
    )
{
  // Check for a valid data indication
  if (DataIndication != NULL)
  {
    // Loop through the list of data indication structures
    while (DataIndication != NULL)
    {
      // Process the data in the data indication structure
      ...

      // Move to the next data indication structure
      DataIndication = DataIndication->Next;
    }

    // Return status indicating the data was received
    return STATUS_SUCCESS;
  }

  // Error
  else
  {
    // Close the socket
    ...

    // Return success since no data was indicated
    return STATUS_SUCCESS;
  }
}

연결 지향 소켓의 WskReceiveEvent 이벤트 콜백 함수가 DataIndication 매개 변수가 가리키는 WSK_DATA_INDICATION 구조 목록에 포함된 모든 데이터를 검색하지 않는 경우 STATUS_PENDING 반환하여 추가 처리를 위해 목록을 유지할 수 있습니다. 이 경우 WSK 애플리케이션은 WskRelease 함수를 호출하여 목록의 구조체에서 모든 데이터 검색을 완료한 후 WSK_DATA_INDICATION 구조 목록을 WSK 하위 시스템에 다시 해제해야 합니다.

연결 지향 소켓의 WskReceiveEvent 이벤트 콜백 함수가 수신된 데이터의 총 바이트 수 중 일부만 허용하는 경우 BytesAccepted 매개 변수가 가리키는 변수를 실제로 수락된 데이터 바이트 수로 설정해야 합니다. 그러나 소켓의 WskReceiveEvent 이벤트 콜백 함수가 받은 모든 데이터를 허용하는 경우 BytesAccepted 매개 변수가 가리키는 변수를 설정할 필요가 없습니다.