Compartilhar via


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

A função LPWSPRecvFrom recebe um datagrama e armazena o endereço de origem.

Sintaxe

LPWSPRECVFROM Lpwsprecvfrom;

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

Parâmetros

[in] s

Descritor que identifica um soquete.

[in, out] lpBuffers

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

Número de estruturas WSABUF na matriz lpBuffers .

[out] lpNumberOfBytesRecvd

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

[in, out] lpFlags

Ponteiro para sinalizadores.

[out] lpFrom

Ponteiro opcional para um buffer na estrutura sockaddr que manterá o endereço de origem após a conclusão da operação sobreposta.

[in, out] lpFromlen

Ponteiro para o tamanho do buffer lpFrom , em bytes, necessário somente se lpFrom for especificado.

[in] lpOverlapped

Ponteiro para uma estrutura WSAOverlapped (ignorada para soquetes não sobrepostos).

[in] lpCompletionRoutine

Tipo: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

Ponteiro para a rotina de conclusão chamada quando a operação de recebimento foi concluída (ignorada para soquetes não sobrepostos).

\\[in\\] lpThreadId

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.

[in, out] lpErrno

Ponteiro para o código de erro.

Valor retornado

Se nenhum erro ocorrer e a operação de recebimento for concluída imediatamente, LPWSPRecvFrom 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.
WSAEFAULT
O parâmetro lpFromlen era inválido: o buffer lpFrom era muito pequeno para acomodar o endereço par ou lpbuffers não está totalmente contido em uma parte válida do espaço de endereço do usuário.
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.
WSAEINVAL
O soquete não foi associado (por exemplo, com LPWSPBind) ou o soquete não foi criado com o sinalizador sobreposto.
WSAEISCONN
O soquete está conectado. Essa função não é permitida com um soquete conectado, independentemente de o soquete ser orientado para conexão ou sem conexão.
WSAENETRESET
A conexão foi interrompida porque a atividade de manutenção de funcionamento detectou uma falha enquanto a operação estava em andamento.
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 executar LPWSPRecvFrom em um soquete depois que LPWSPShutdown foi invocado com a definição de 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.
WSAECONNRESET
O circuito virtual foi redefinido pelo lado remoto executando um fechamento forçado ou por anulação. O aplicativo deve fechar o soquete porque ele não pode ser mais usado. Em um soquete de datagrama UDP, esse erro indicaria que uma operação de envio anterior resultou em uma mensagem "Porta Inacessível" ICMP.
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

A função LPWSPRecvFrom é usada principalmente em um soquete sem conexão especificado por s O soquete não deve ser conectado. O endereço local do soquete deve ser conhecido. Isso pode ser feito explicitamente por meio de LPWSPBind ou implicitamente por meio de LPWSPSendTo ou LPWSPJoinLeaf.

Para soquetes sobrepostos, essa função é usada para postar um ou mais buffers nos quais os dados de entrada serão colocados à medida que ficam disponíveis em um soquete (possivelmente conectado), após o qual ocorre a indicação de conclusão especificada pelo cliente (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. Observe também que os valores apontados por lpFrom e lpFromlen não são atualizados até que a conclusão seja indicada. Os aplicativos não devem usar ou perturbar esses valores até que tenham sido atualizados, portanto, o cliente não deve usar variáveis automáticas (ou seja, baseadas em pilha) para esses parâmetros.

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 de acordo com a semântica de bloqueio atribuída para LPWSPRecv.

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 tipos de soquete sem conexão, o endereço do qual os dados se originaram é copiado para o buffer apontado por lpFrom. Na entrada, o valor apontado por lpFromlen é inicializado para o tamanho desse buffer e é modificado após a conclusão para indicar o tamanho real do endereço armazenado lá.

Conforme observado anteriormente para soquetes sobrepostos, os parâmetros lpFrom e lpFromlen não são atualizados até que a E/S sobreposta seja concluída. A memória apontada por esses parâmetros deve, portanto, permanecer disponível para o provedor de serviços e não pode ser alocada no quadro de pilha do cliente SPI do Windows Sockets. Os parâmetros lpFrom e lpFromlen são ignorados para soquetes orientados à conexão.

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, uma única 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 para o soquete e as operações de recebimento subsequentes recuperarão o restante da mensagem. Se MSG_PARTIAL não tiver suporte, mas o protocolo for confiável, LPWSPRecvFrom 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 LPWSPRecvFrom gera o erro WSAEMSGSIZE.

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.

 

 

Para soquetes orientados a mensagens, o bit MSG_PARTIAL será definido no parâmetro lpFlags se uma mensagem parcial for recebida. Se uma mensagem completa for recebida, MSG_PARTIAL será limpa em lpFlags. No caso de conclusão atrasada, o valor apontado por lpFlags não é atualizado. Quando a conclusão for indicada, o cliente SPI do Windows Sockets deverá chamar LPWSPGetOverlappedResult e examinar os sinalizadores apontados pelo parâmetro lpdwFlags .

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 é concluída, 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 examinando o parâmetro lpdwFlags de LPWSPGetOverlappedResult.

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. Um 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. É 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. 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 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. 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, embora não necessariamente na mesma ordem em que as operações sobrepostas sejam 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

   
Cliente mínimo com suporte Windows 2000 Professional [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows 2000 Server [somente aplicativos da área de trabalho]
Cabeçalho ws2spi.h

Confira também

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket