Função de retorno de chamada LPWSPRECV (ws2spi.h)

A função LPWSPRecv recebe dados em um soquete.

Sintaxe

LPWSPRECV Lpwsprecv;

int Lpwsprecv(
  [in]         SOCKET s,
  \[in\, out\] LPWSABUF lpBuffers,
  [in]         DWORD dwBufferCount,
  [out]        LPDWORD lpNumberOfBytesRecvd,
  \[in\, out\] LPDWORD lpFlags,
  [in]         LPWSAOVERLAPPED lpOverlapped,
  [in]         LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  [in]         LPWSATHREADID lpThreadId,
  [out]        LPINT lpErrno
)
{...}

Parâmetros

[in] s

Um descritor que identifica um soquete conectado.

\\[in\\, out\\] lpBuffers

Um ponteiro para uma matriz de estruturas WSABUF . Cada estrutura WSABUF contém um ponteiro para um buffer e o comprimento do buffer, em bytes.

[in] dwBufferCount

O número de estruturas WSABUF na matriz lpBuffers .

[out] lpNumberOfBytesRecvd

Um ponteiro para o número de bytes recebidos por essa chamada.

\\[in\\, out\\] lpFlags

Um ponteiro para sinalizadores que especificam a maneira como a chamada é feita.

[in] lpOverlapped

Um ponteiro para uma estrutura WSAOverlapped (ignorado para estruturas não sobrepostas).

[in] lpCompletionRoutine

Tipo: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

Um ponteiro para a rotina de conclusão chamado quando a operação de recebimento foi concluída (ignorado para estruturas não sobrepostas).

[in] lpThreadId

Um ponteiro para uma estrutura WSATHREADID a ser usada pelo provedor em uma chamada subsequente para WPUQueueApc. O provedor deve armazenar a estrutura WSATHREADID referenciada (não o ponteiro para o mesmo) até que a função WPUQueueApc retorne.

[out] lpErrno

Um ponteiro para o código de erro.

Retornar valor

Se nenhum erro ocorrer e a operação de recebimento for concluída imediatamente, LPWSPRecv retornará zero. Observe que, nesse caso, a rotina de conclusão, se especificada, já terá sido enfileirada. Caso contrário, um valor de SOCKET_ERROR será retornado e um código de erro específico estará disponível em lpErrno. O código de erro WSA_IO_PENDING indica que a operação sobreposta foi iniciada com êxito e que a conclusão será indicada posteriormente. Qualquer outro código de erro indica que nenhuma operação sobreposta foi iniciada e nenhuma indicação de conclusão ocorrerá.

Código do Erro Significado
WSAENETDOWN
O subsistema de rede falhou.
WSAENOTCONN
O soquete não está conectado.
WSAEINTR
A chamada (bloqueio) foi cancelada por meio de LPWSPCancelBlockingCall.
WSAEINPROGRESS
O bloqueio da chamada do Windows Sockets está em andamento ou o provedor de serviços ainda está processando uma função de retorno de chamada.
WSAENETRESET
A conexão foi interrompida porque a atividade de manutenção de funcionamento detectou uma falha enquanto a operação estava em andamento.
WSAEFAULT
O parâmetro lpBuffers não está totalmente contido em uma parte válida do espaço de endereço do usuário.
WSAENOTSOCK
O descritor não é um soquete.
WSAEOPNOTSUPP
MSG_OOB foi especificado, mas o soquete não é estilo de fluxo, como tipo SOCK_STREAM, não há suporte para dados OOB no domínio de comunicação associado a esse soquete ou o soquete é unidirecional e dá suporte apenas a operações de envio.
WSAESHUTDOWN
Soquete foi desligado; não é possível receber por meio de LPWSPRecv em um soquete depois que LPWSPShutdown foi invocado com como definido como SD_RECEIVE ou SD_BOTH.
WSAEWOULDBLOCK
Windows NT: soquetes sobrepostos: há muitas solicitações de E/S sobrepostas pendentes. Soquetes não sobrepostos: o soquete é marcado como não desbloqueio e a operação de recebimento não pode ser concluída imediatamente.
WSAEMSGSIZE
A mensagem era muito grande para caber no buffer especificado e (somente para protocolos não confiáveis) qualquer parte à direita da mensagem que não se encaixasse no buffer foi descartada.
WSAEINVAL
O soquete não foi associado (por exemplo, com LPWSPBind) ou o soquete não foi criado com o sinalizador sobreposto.
WSAECONNABORTED
O circuito virtual foi encerrado devido a um tempo limite ou outra falha.
WSAECONNRESET
O circuito virtual foi redefinido pelo lado remoto.
WSAEDISCON
Soquetes são orientados a mensagens e o circuito virtual foi normalmente fechado pelo lado remoto.
WSA_IO_PENDING
Uma operação sobreposta foi iniciada com êxito e a conclusão será indicada posteriormente.
WSA_OPERATION_ABORTED
A operação sobreposta foi cancelada devido ao fechamento do soquete.

Comentários

LPWSPRecv é usado em soquetes conectados ou soquetes sem conexão associados especificados pelo parâmetro s e é usado para ler dados de entrada. O endereço local do soquete deve ser conhecido. Isso pode ser feito explicitamente por meio de LPWSPBind ou implicitamente por meio de LPWSPAccept, LPWSPConnect, LPWSPSendTo ou LPWSPJoinLeaf.

Para soquetes conectados e sem conexão, essa função restringe os endereços dos quais as mensagens recebidas são aceitas. A função retorna apenas mensagens do endereço remoto especificado na conexão. As mensagens de outros endereços são (silenciosamente) descartadas.

Para soquetes sobrepostos, LPWSPRecv é usado para postar um ou mais buffers nos quais os dados de entrada serão colocados à medida que ficam disponíveis, após o qual ocorre a indicação de conclusão especificada pelo cliente SPI do Windows Sockets (invocação da rotina de conclusão ou configuração de um objeto de evento). Se a operação não for concluída imediatamente, o status de conclusão final será recuperado por meio da rotina de conclusão ou LPWSPGetOverlappedResult.

Se lpOverlapped e lpCompletionRoutine forem nulos, o soquete nessa função será tratado como um soquete não sobreposto.

Para soquetes não sobrepostos, os parâmetros lpOverlapped, lpCompletionRoutine e lpThreadId são ignorados. Todos os dados que já foram recebidos e armazenados em buffer pelo transporte serão copiados para os buffers de usuário fornecidos. Para o caso de um soquete de bloqueio sem dados recebidos e armazenados em buffer pelo transporte, a chamada será bloqueada até que os dados sejam recebidos. O Windows Sockets 2 não define nenhum mecanismo de tempo limite de bloqueio padrão para essa função. Para protocolos que atuam como protocolos de fluxo de bytes, a pilha tenta retornar o máximo de dados possível sujeito ao espaço de buffer fornecido e à quantidade de dados recebidos disponíveis. No entanto, o recebimento de um único byte é suficiente para desbloquear o chamador. Não há nenhuma garantia de que mais de um único byte será retornado. Para protocolos que atuam como orientados a mensagens, uma mensagem completa é necessária para desbloquear o chamador.

Se um protocolo está ou não agindo como fluxo de bytes é determinado pela configuração de XP1_MESSAGE_ORIENTED e XP1_PSEUDO_STREAM em sua estrutura WSAPROTOCOL_INFO e a configuração do sinalizador de MSG_PARTIAL passado para essa função (para protocolos que dão suporte a ele). As combinações relevantes são resumidas na tabela a seguir (um asterisco (*) indica que a configuração desse bit não importa nesse caso).

XP1_MESSAGE_ORIENTED XP1_PSEUDO_STREAM MSG_PARTIAL Atua como
não definido * * fluxo de bytes
* set * fluxo de bytes
set não definido set fluxo de bytes
set não definido não definido orientado a mensagens

Os buffers fornecidos são preenchidos na ordem em que aparecem na matriz apontada por lpBuffers e os buffers são empacotados para que nenhum orifício seja criado.

A matriz de estruturas WSABUF apontadas pelo parâmetro lpBuffers é transitória. Se essa operação for concluída de maneira sobreposta, será responsabilidade do provedor de serviços capturar essa matriz de ponteiros para estruturas WSABUF antes de retornar dessa chamada. Isso permite que os clientes SPI do Windows Sockets criem matrizes WSABUF baseadas em pilha.

Para soquetes no estilo de fluxo de bytes (por exemplo, tipo SOCK_STREAM), os dados de entrada são colocados nos buffers até que os buffers sejam preenchidos, a conexão seja fechada ou os dados armazenados em buffer sejam esgotados internamente. Independentemente de os dados de entrada preencherem ou não todos os buffers, a indicação de conclusão ocorre para soquetes sobrepostos. Para soquetes orientados a mensagens (por exemplo, digite SOCK_DGRAM), uma mensagem de entrada é colocada nos buffers fornecidos, até o tamanho total dos buffers fornecidos e a indicação de conclusão ocorre para soquetes sobrepostos. Se a mensagem for maior que os buffers fornecidos, os buffers serão preenchidos com a primeira parte da mensagem. Se o recurso MSG_PARTIAL tiver suporte do provedor de serviços, o sinalizador MSG_PARTIAL será definido em lpFlags e as operações de recebimento subsequentes poderão ser usadas para recuperar o restante da mensagem. Se MSG_PARTIAL não tiver suporte, mas o protocolo for confiável, LPWSPRecv gerará o erro WSAEMSGSIZE e uma operação de recebimento subsequente com um buffer maior poderá ser usada para recuperar toda a mensagem. Caso contrário, (ou seja, o protocolo não é confiável e não dá suporte a MSG_PARTIAL), o excesso de dados é perdido e LPWSPRecv gera o erro WSAEMSGSIZE.

Para soquetes orientados a conexão, LPWSPRecv pode indicar o encerramento normal do circuito virtual de uma de duas maneiras, dependendo se o soquete é um fluxo de bytes ou orientado a mensagens. Para fluxos de bytes, zero bytes que foram lidos indicam um fechamento normal e que nenhum bytes será lido. Para soquetes orientados a mensagens, em que uma mensagem de byte zero geralmente é permitida, um código de erro de retorno de WSAEDISCON é usado para indicar o fechamento normal. De qualquer forma, um código de erro de retorno de WSAECONNRESET indica que ocorreu um fechamento abortivo.

O parâmetro lpFlags pode ser usado para influenciar o comportamento da invocação de função além das opções especificadas para o soquete associado. Ou seja, a semântica dessa função é determinada pelas opções de soquete e pelo parâmetro lpFlags . Este último é construído usando o operador OR bit a bit com qualquer um dos valores a seguir.

Valor Significado
MSG_PEEK Espia os dados de entrada. Os dados são copiados para o buffer, mas não são removidos da fila de entrada. Esse sinalizador é válido apenas para soquetes não sobrepostos.
MSG_OOB Processa dados fora de banda (OOB).
MSG_PARTIAL Esse sinalizador destina-se apenas a soquetes orientados a mensagens. Na saída, indica que os dados fornecidos são uma parte da mensagem transmitida pelo remetente. As partes restantes da mensagem serão fornecidas em operações de recebimento subsequentes. Uma operação de recebimento subsequente com MSG_PARTIAL sinalizador limpo indica o fim da mensagem do remetente. Como parâmetro de entrada, MSG_PARTIAL indica que a operação de recebimento deve ser concluída mesmo que apenas parte de uma mensagem tenha sido recebida pelo provedor de serviços.

Se uma operação sobreposta for concluída imediatamente, LPWSPRecv retornará um valor igual a zero e o parâmetro lpNumberOfBytesRecvd será atualizado com o número de bytes recebidos e os bits de sinalizador apontados pelo parâmetro lpFlags também serão atualizados . Se a operação sobreposta for iniciada com êxito e for concluída posteriormente, LPWSPRecv retornará SOCKET_ERROR e indicará o código de erro WSA_IO_PENDING. Nesse caso, lpNumberOfBytesRecvd e lpFlags não são atualizados . Quando a operação sobreposta conclui, a quantidade de dados transferidos é indicada por meio do parâmetro cbTransferred na rotina de conclusão (se especificada) ou por meio do parâmetro lpcbTransfer em LPWSPGetOverlappedResult. Os valores de sinalizador são obtidos por meio do parâmetro dwFlags da rotina de conclusão ou examinando o parâmetro lpdwFlags de WSAGetOverlappedResult.

Os provedores devem permitir que essa função seja chamada de dentro da rotina de conclusão de uma função LPWSPRecv, LPWSPRecvFrom, LPWSPSend ou LPWSPSendTo anterior. No entanto, para um determinado soquete, as rotinas de conclusão de E/S não podem ser aninhadas. Isso permite que transmissões de dados sensíveis ao tempo ocorram inteiramente dentro de um contexto preemptivo.

O parâmetro lpOverlapped deve ser válido durante a operação sobreposta. Se várias operações de E/S estiverem pendentes simultaneamente, cada uma deverá referenciar uma estrutura sobreposta separada. A estrutura WSAOverlapped é definida em sua própria página de referência.

Se o parâmetro lpCompletionRoutine for nulo, o provedor de serviços sinalizará o membro hEvent de lpOverlapped quando a operação sobreposta for concluída se contiver um identificador de objeto de evento válido. O cliente SPI do Windows Sockets pode usar LPWSPGetOverlappedResult para aguardar ou sondar o objeto de evento.

Se lpCompletionRoutine não for nulo, o membro hEvent será ignorado e poderá ser usado pelo cliente SPI do Windows Sockets para passar informações de contexto para a rotina de conclusão. Um cliente que passa um lpCompletionRoutine nulo e, posteriormente, chama WSAGetOverlappedResult para a mesma solicitação de E/S sobreposta pode não definir o parâmetro fWait para essa invocação de WSAGetOverlappedResult como TRUE. Nesse caso, o uso do membro hEvent é indefinido e a tentativa de aguardar o membro hEvent produziria resultados imprevisíveis.

É responsabilidade do provedor de serviços organizar a invocação da rotina de conclusão especificada pelo cliente quando a operação sobreposta for concluída. Como a rotina de conclusão deve ser executada no contexto do mesmo thread que iniciou a operação sobreposta, ela não pode ser invocada diretamente do provedor de serviços. O Ws2_32.dll oferece um mecanismo de APC (chamada de procedimento assíncrono) para facilitar a invocação de rotinas de conclusão.

Um provedor de serviços organiza a execução de uma função no thread e no contexto de processo adequados chamando WPUQueueApc, que foi usado para iniciar a operação sobreposta. Essa função pode ser chamada de qualquer contexto de processo e thread, até mesmo de um contexto diferente do thread e do processo que foi usado para iniciar a operação sobreposta.

WPUQueueApc usa como parâmetros de entrada um ponteiro para uma estrutura WSATHREADID (fornecida ao provedor por meio do parâmetro de entrada lpThreadId ), um ponteiro para uma função APC a ser invocada e um valor de contexto que é posteriormente passado para a função APC. Como apenas um único valor de contexto está disponível, a função APC em si não pode ser a rotina de conclusão especificada pelo cliente. Em vez disso, o provedor de serviços deve fornecer um ponteiro para sua própria função APC que usa o valor de contexto fornecido para acessar as informações de resultado necessárias para a operação sobreposta e, em seguida, invoca a rotina de conclusão especificada pelo cliente.

O protótipo para a rotina de conclusão fornecida pelo cliente é o seguinte.

void CALLBACK 
CompletionRoutine(  
  IN DWORD           dwError, 
  IN DWORD           cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD           dwFlags 
);

O parâmetro CompletionRoutine é um espaço reservado para um nome de função fornecido pelo cliente. dwError especifica o status de conclusão para a operação sobreposta, conforme indicado por lpOverlapped. O parâmetro cbTransferred especifica o número de bytes recebidos. dwFlags contém informações que teriam aparecido em lpFlags se a operação de recebimento tivesse sido concluída imediatamente. Essa função não retorna um valor.

As rotinas de conclusão podem ser chamadas em qualquer ordem, mas não necessariamente na mesma ordem em que as operações sobrepostas são concluídas. No entanto, os buffers postados têm a garantia de serem preenchidos na mesma ordem em que são fornecidos.

Observação

Todas as E/S iniciadas por um determinado thread são canceladas quando esse thread é encerrado. Para soquetes sobrepostos, as operações assíncronas pendentes poderão falhar se o thread for fechado antes da conclusão das operações. Consulte ExitThread para obter mais informações.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows 10 Build 20348
Servidor mínimo com suporte Windows 10 Build 20348
Cabeçalho ws2spi.h

Confira também

WPUCloseEvent

WPUCreateEvent

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket