Função WSAAsyncSelect (winsock.h)
[A função WSAAsyncSelect está disponível para uso nos sistemas operacionais especificados na seção Requisitos. Ele poderá ser alterado ou ficar indisponível em versões subsequentes. Em vez de usar E/S no estilo Select, use E /S sobreposta e objetos de evento com WinSock2.]
A função WSAAsyncSelect solicita notificação baseada em mensagem do Windows de eventos de rede para um soquete.
Sintaxe
int WSAAsyncSelect(
[in] SOCKET s,
[in] HWND hWnd,
[in] u_int wMsg,
[in] long lEvent
);
Parâmetros
[in] s
Um descritor que identifica o soquete para o qual a notificação de evento é necessária.
[in] hWnd
Um identificador que identifica a janela que receberá uma mensagem quando ocorrer um evento de rede.
[in] wMsg
Uma mensagem a ser recebida quando ocorrer um evento de rede.
[in] lEvent
Uma máscara de bits, a qual especifica uma combinação de eventos de rede em que o aplicativo está interessado.
Retornar valor
Se a função WSAAsyncSelect for bem-sucedida, o valor retornado será zero, desde que a declaração de interesse do aplicativo no conjunto de eventos de rede tenha sido bem-sucedida. Caso contrário, o valor SOCKET_ERROR será retornado e um número de erro específico poderá ser recuperado chamando WSAGetLastError.
Código do erro | Significado |
---|---|
Uma chamada WSAStartup bem-sucedida deve ocorrer antes de usar essa função. | |
Falha no subsistema de rede. | |
Um dos parâmetros especificados era inválido, como o identificador de janela que não se refere a uma janela existente ou o soquete especificado está em um estado inválido. | |
Uma chamada do Windows Sockets 1.1 de bloqueio está em andamento ou o provedor de serviços ainda está processando uma função de retorno de chamada. | |
O descritor não é um soquete. |
Códigos de erro adicionais podem ser definidos quando uma janela do aplicativo recebe uma mensagem. Esse código de erro é extraído do lParam na mensagem de resposta usando a macro WSAGETSELECTERROR . Os códigos de erro possíveis para cada evento de rede são listados na tabela a seguir.
Evento: FD_CONNECT
Código do erro | Significado |
---|---|
WSAEAFNOSUPPORT | Os endereços na família especificada não podem ser usados com este soquete. |
WSAECONNREFUSED | A tentativa de conexão foi rejeitada. |
WSAENETUNREACH | A rede não pode ser alcançada através deste host neste momento. |
WSAEFAULT | O parâmetro namelen é inválido. |
WSAEINVAL | O soquete já está associado a um endereço. |
WSAEISCONN | O soquete já está conectado. |
WSAEMFILE | Nenhum outro descritor de arquivo disponível. |
WSAENOBUFS | Nenhum espaço de buffer disponível. O soquete não pode ser conectado. |
WSAENOTCONN | O soquete não está conectado. |
WSAETIMEDOUT | Tente se conectar com o tempo limite sem estabelecer uma conexão. |
Evento: FD_CLOSE
Código do erro | Significado |
---|---|
WSAENETDOWN | Falha no subsistema de rede. |
WSAECONNRESET | A conexão foi redefinida pelo lado remoto. |
WSAECONNABORTED | A conexão foi encerrada devido a um tempo limite ou outra falha. |
Código do erro | Significado |
---|---|
WSAENETDOWN | Falha no subsistema de rede. |
Evento: FD_ROUTING_INTERFACE_CHANGE
Código do erro | Significado |
---|---|
WSAENETUNREACH | O destino especificado não é mais acessível. |
WSAENETDOWN | Falha no subsistema de rede. |
Comentários
A função WSAAsyncSelect é usada para solicitar que WS2_32.DLL envie uma mensagem para a janela hWnd quando detectar qualquer evento de rede especificado pelo parâmetro lEvent . A mensagem que deve ser enviada é especificada pelo parâmetro wMsg . O soquete para o qual a notificação é necessária é identificado pelo parâmetro s .
A função WSAAsyncSelect define automaticamente soquetes como modo sem bloqueio, independentemente do valor de lEvent. Para definir o soquete de volta para o modo de bloqueio, primeiro é necessário limpar o registro de evento associado a soquetes por meio de uma chamada para WSAAsyncSelect com lEvent definido como zero. Em seguida, você pode chamar ioctlsocket ou WSAIoctl para definir o soquete de volta para o modo de bloqueio. Para obter mais informações sobre como definir o soquete sem bloqueio de volta para o modo de bloqueio, consulte as funções ioctlsocket e WSAIoctl .
O parâmetro lEvent é construído usando o operador OR bit a bit com qualquer valor listado na tabela a seguir.
Valor | Significado |
---|---|
FD_READ | Defina para receber notificação de preparação para leitura. |
FD_WRITE | Deseja receber uma notificação de preparação para gravação. |
FD_OOB | Deseja receber uma notificação da chegada de dados OOB. |
FD_ACCEPT | Deseja receber notificação de conexões de entrada. |
FD_CONNECT | Deseja receber uma notificação da conexão concluída ou da operação de junção de vários pontos. |
FD_CLOSE | Deseja receber uma notificação de fechamento do soquete. |
FD_QOS | Deseja receber uma notificação de alterações de QoS (Qualidade de Serviço) do soquete. |
FD_GROUP_QOS | Deseja receber uma notificação de alterações de QoS (Qualidade de Serviço) do grupo de soquetes (reservado para uso futuro com grupos de soquetes). Reservado. |
FD_ROUTING_INTERFACE_CHANGE | Deseja receber uma notificação de alterações de interface de roteamento para os destinos especificados. |
FD_ADDRESS_LIST_CHANGE | Deseja receber uma notificação de alterações na lista de endereços local para a família de protocolos de soquete. |
A emissão de um WSAAsyncSelect para um soquete cancela qualquer WSAAsyncSelect ou WSAEventSelect anterior para o mesmo soquete. Por exemplo, para receber notificação para leitura e gravação, o aplicativo deve chamar WSAAsyncSelect com FD_READ e FD_WRITE, da seguinte maneira:
rc = WSAAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE);
Não é possível especificar mensagens diferentes para eventos diferentes. O código a seguir não funcionará; a segunda chamada cancelará os efeitos do primeiro e somente FD_WRITE eventos serão relatados com a mensagem wMsg2:
rc = WSAAsyncSelect(s, hWnd, wMsg1, FD_READ);
rc = WSAAsyncSelect(s, hWnd, wMsg2, FD_WRITE);
Para cancelar todas as notificações que indicam que o Windows Sockets não deve enviar mais mensagens relacionadas a eventos de rede no soquete, lEvent está definido como zero.
rc = WSAAsyncSelect(s, hWnd, 0, 0);
Embora WSAAsyncSelect desabilite imediatamente a postagem de mensagens de evento para o soquete nessa instância, é possível que as mensagens possam estar aguardando na fila de mensagens do aplicativo. Portanto, o aplicativo deve estar preparado para receber mensagens de evento de rede mesmo após o cancelamento. Fechar um soquete com closesocket também cancela o envio de mensagens WSAAsyncSelect , mas a mesma ressalva sobre mensagens na fila ainda se aplica.
O soquete criado pela função accept tem as mesmas propriedades que o soquete de escuta usado para aceitá-lo. Consequentemente, os eventos WSAAsyncSelect definidos para o soquete de escuta também se aplicam ao soquete aceito. Por exemplo, se um soquete de escuta tiver eventos WSAAsyncSelectFD_ACCEPT, FD_READ e FD_WRITE, qualquer soquete aceito nesse soquete de escuta também terá eventos FD_ACCEPT, FD_READ e FD_WRITE com o mesmo valor wMsg usado para mensagens. Se um wMsg ou eventos diferentes forem desejados, o aplicativo deverá chamar WSAAsyncSelect, passando o soquete aceito e os novos dados desejados.
Quando um dos eventos de rede indicados ocorre nos soquetes especificados, a janela do aplicativo hWnd recebe a mensagem wMsg. O parâmetro wParam identifica o soquete no qual ocorreu um evento de rede. A palavra baixa de lParam especifica o evento de rede que ocorreu. A palavra alta de lParam contém qualquer código de erro. O código de erro é qualquer erro, conforme definido em Winsock2.h.
#include <windows.h>
#define WSAGETSELECTEVENT(lParam) LOWORD(lParam)
#define WSAGETSELECTERROR(lParam) HIWORD(lParam)
O uso dessas macros maximizará a portabilidade do código-fonte para o aplicativo.
Os possíveis códigos de evento de rede que podem ser retornados estão listados na tabela a seguir.
Valor | Significado |
---|---|
FD_READ | Soquete pronto para leitura. |
FD_WRITE | Soquete pronto para gravação. |
FD_OOB | Dados OOB prontos para leitura em soquetes |
FD_ACCEPT | O soquete está pronto para aceitar uma nova conexão de entrada. |
FD_CONNECT | Operação de conexão ou junção de vários pontos iniciada no soquete concluído . |
FD_CLOSE | A conexão identificada pelo soquete s foi fechada. |
FD_QOS | A qualidade do serviço associada ao soquete s foi alterada. |
FD_GROUP_QOS | Reservado. A qualidade de serviço associada ao grupo de soquetes ao qual s pertence foi alterada (reservada para uso futuro com grupos de soquetes). |
FD_ROUTING_INTERFACE_CHANGE | A interface local que deve ser usada para enviar para o destino especificado foi alterada. |
FD_ADDRESS_LIST_CHANGE | A lista de endereços da família de protocolos de soquete à qual o cliente do aplicativo pode associar foi alterada. |
Embora WSAAsyncSelect possa ser chamado com interesse em vários eventos, a janela do aplicativo receberá uma única mensagem para cada evento de rede.
Como no caso da função select , WSAAsyncSelect será usado com frequência para determinar quando uma operação de transferência de dados (enviar ou rev) pode ser emitida com a expectativa de êxito imediato. No entanto, um aplicativo robusto deve ser preparado para a possibilidade de receber uma mensagem e emitir uma chamada do Windows Sockets 2 que retorna WSAEWOULDBLOCK imediatamente. Por exemplo, a seguinte sequência de eventos é possível:
- Os dados chegam no soquete s; Mensagem WSAAsyncSelect de postagens do Windows Sockets 2
- O aplicativo processa outra mensagem
- Durante o processamento, o aplicativo emite um
ioctlsocket(s, FIONREAD...)
e observa que há dados prontos para serem lidos - O aplicativo emite um
recv(s,...)
para ler os dados - O aplicativo executa um loop para processar a próxima mensagem, chegando eventualmente à mensagem WSAAsyncSelect indicando que os dados estão prontos para leitura
- O aplicativo emite
recv(s,...)
, que falha com o erro WSAEWOULDBLOCK.
O WS2_32.DLL não inundará continuamente um aplicativo com mensagens para um evento de rede específico. Depois de postar com êxito a notificação de um evento específico em uma janela do aplicativo, nenhuma mensagem adicional para esse evento de rede será postada na janela do aplicativo até que o aplicativo faça a chamada de função que reabilita implicitamente a notificação desse evento de rede.
Evento | Função reenabling |
---|---|
FD_READ | recv, recvfrom, WSARecv ou WSARecvFrom. |
FD_WRITE | send, sendto, WSASend ou WSASendTo. |
FD_OOB | recv, recvfrom, WSARecv ou WSARecvFrom. |
FD_ACCEPT | accept ou WSAAccept , a menos que o código de erro seja WSATRY_AGAIN indicando que a função de condição retornada CF_DEFER. |
FD_CONNECT | Nenhum. |
FD_CLOSE | Nenhum. |
FD_QOS | WSAIoctl com SIO_GET_QOS de comando. |
FD_GROUP_QOS | Reservado. WSAIoctl com SIO_GET_GROUP_QOS de comando (reservado para uso futuro com grupos de soquetes). |
FD_ROUTING_INTERFACE_CHANGE | WSAIoctl com SIO_ROUTING_INTERFACE_CHANGE de comando. |
FD_ADDRESS_LIST_CHANGE | WSAIoctl com SIO_ADDRESS_LIST_CHANGE de comando. |
Qualquer chamada para a rotina de reassovamento, mesmo que falhe, resulta em uma nova busca de postagem de mensagens para o evento relevante.
Para eventos FD_READ, FD_OOB e FD_ACCEPT , a postagem de mensagens é disparada em nível. Isso significa que, se a rotina de nova inicialização for chamada e a condição relevante ainda for atendida após a chamada, uma mensagem WSAAsyncSelect será postada no aplicativo. Isso permite que um aplicativo seja controlado por eventos e não se preocupo com a quantidade de dados que chega ao mesmo tempo. Considere a sequência a seguir:
- A pilha de transporte de rede recebe 100 bytes de dados em soquetes e faz com que o Windows Sockets 2 poste uma mensagem de FD_READ .
- O aplicativo emite recv( s, buffptr, 50, 0) para ler 50 bytes.
- Outra mensagem FD_READ é postada porque ainda há dados a serem lidos.
Os eventos FD_QOS e FD_GROUP_QOS são considerados disparados pela borda. Uma mensagem será postada exatamente uma vez quando ocorrer uma alteração de qualidade de serviço. Outras mensagens não serão enviadas até que o provedor detecte uma nova alteração na qualidade do serviço ou o aplicativo renegocie a qualidade do serviço para o soquete.
A mensagem FD_ROUTING_INTERFACE_CHANGE é postada quando a interface local que deve ser usada para alcançar o destino especificado em WSAIoctl com SIO_ROUTING_INTERFACE_CHANGE é alterada após a emissão desse IOCTL.
A mensagem FD_ADDRESS_LIST_CHANGE é postada quando a lista de endereços aos quais o aplicativo pode associar alterações após a emissão do WSAIoctl com SIO_ADDRESS_LIST_CHANGE.
Se algum evento tiver ocorrido quando o aplicativo chamar WSAAsyncSelect ou quando a função reenabling for chamada, uma mensagem será postada conforme apropriado. Por exemplo, considere a seguinte sequência:
- Um aplicativo chama listen.
- Uma solicitação de conexão é recebida, mas ainda não aceita.
- O aplicativo chama WSAAsyncSelect especificando que ele requer o recebimento FD_ACCEPT mensagens para o soquete. Devido à persistência de eventos, o Windows Sockets 2 posta uma mensagem FD_ACCEPT imediatamente.
O evento FD_WRITE é tratado de forma ligeiramente diferente. Uma mensagem FD_WRITE é postada quando um soquete é conectado pela primeira vez com connect ou WSAConnect (após FD_CONNECT, se também registrado) ou aceito com accept ou WSAAccept, e depois que uma operação de envio falha com WSAEWOULDBLOCK e o espaço de buffer fica disponível. Portanto, um aplicativo pode assumir que os envios são possíveis a partir da primeira mensagem FD_WRITE e durando até que um envio retorne WSAEWOULDBLOCK. Após essa falha, o aplicativo será notificado de que os envios são novamente possíveis com uma mensagem FD_WRITE .
O evento FD_OOB é usado somente quando um soquete é configurado para receber dados OOB separadamente. Se o soquete estiver configurado para receber dados OOB embutidos, os dados OOB (agilizados) serão tratados como dados normais e o aplicativo deverá registrar um interesse em, e receberá, FD_READ eventos, não FD_OOB eventos. Um aplicativo pode definir ou inspecionar a maneira como os dados OOB devem ser tratados usando setsockopt ou getsockopt para a opção SO_OOBINLINE.
O código de erro em uma mensagem FD_CLOSE indica se o fechamento do soquete foi normal ou anulativo. Se o código de erro for zero, o fechamento foi normal; se o código de erro for WSAECONNRESET, o circuito virtual do soquete será redefinido. Isso só se aplica a soquetes orientados à conexão, como SOCK_STREAM.
A mensagem FD_CLOSE é postada quando uma indicação próxima é recebida para o circuito virtual correspondente ao soquete. Em termos TCP, isso significa que o FD_CLOSE é postado quando a conexão entra nos estados TIME WAIT ou CLOSE WAIT. Isso resulta da extremidade remota executando um desligamento no lado de envio ou um closesocket. FD_CLOSE só deve ser postado depois que todos os dados são lidos de um soquete, mas um aplicativo deve marcar para os dados restantes após o recebimento de FD_CLOSE para evitar qualquer possibilidade de perda de dados.
Lembre-se de que o aplicativo receberá apenas uma mensagem FD_CLOSE para indicar o fechamento de um circuito virtual e somente quando todos os dados recebidos forem lidos se este for um fechamento normal. Ele não receberá uma mensagem FD_READ para indicar essa condição.
A mensagem FD_QOS ou FD_GROUP_QOS é postada quando qualquer parâmetro na especificação de fluxo associado ao soquete ou ao grupo de soquetes ao qual pertence foi alterado, respectivamente. Os aplicativos devem usar WSAIoctl com SIO_GET_QOS de comando ou SIO_GET_GROUP_QOS para obter a qualidade atual do serviço para soquetes ou para o grupo de soquetes ao qual pertence, respectivamente.
Os eventos FD_ROUTING_INTERFACE_CHANGE e FD_ADDRESS_LIST_CHANGE também são considerados gatilhos de borda. Uma mensagem será postada exatamente uma vez quando ocorrer uma alteração depois que o aplicativo solicitar a notificação emitindo WSAIoctl com SIO_ROUTING_INTERFACE_CHANGE ou SIO_ADDRESS_LIST_CHANGE correspondentemente. Outras mensagens não serão enviadas até que o aplicativo reissua o IOCTL e outra alteração seja detectada porque o IOCTL foi emitido.
Aqui está um resumo de eventos e condições para cada mensagem de notificação assíncrona.
-
FD_READ:
- Quando WSAAsyncSelect for chamado, se houver dados disponíveis para receber no momento.
- Quando os dados chegam, se FD_READ ainda não estiverem postados.
- Depois que recv ou recvfrom for chamado, com ou sem MSG_PEEK), se os dados ainda estiverem disponíveis para receber.
Nota Quando setsockopt SO_OOBINLINE está habilitado, os dados incluem dados normais e OOB nas instâncias indicadas acima.
-
FD_WRITE:
- Quando WSAAsyncSelect chamado, se um send ou sendto for possível.
- Depois de conectar ou aceitar chamado, quando a conexão for estabelecida.
- Depois de enviar ou enviar para falhar com WSAEWOULDBLOCK, quando send ou sendto provavelmente terá êxito.
- Depois de associar em um soquete sem conexão. FD_WRITE pode ou não ocorrer neste momento (dependente da implementação). De qualquer forma, um soquete sem conexão é sempre gravável imediatamente após uma operação de associação .
- FD_OOB: válido somente quando setsockopt SO_OOBINLINE estiver desabilitado (padrão).
-
FD_ACCEPT:
- Quando wsaAsyncSelect chamado, se houver atualmente uma solicitação de conexão disponível para aceitar.
- Quando uma solicitação de conexão chega, se ainda não FD_ACCEPT postado.
- Depois de aceitar chamado, se houver outra solicitação de conexão disponível para aceitar.
-
FD_CONNECT:
- Quando WSAAsyncSelect chamado, se houver atualmente uma conexão estabelecida.
- Depois de conectar chamado, quando a conexão é estabelecida, mesmo quando a conexão é bem-sucedida imediatamente, como é típico com um soquete de datagrama.
- Depois de chamar WSAJoinLeaf, quando a operação de junção for concluída.
- Após a conexão, WSAConnect ou WSAJoinLeaf foi chamado com um soquete orientado a conexão sem bloqueio. A operação inicial retornada com um erro específico de WSAEWOULDBLOCK, mas a operação de rede foi adiante. Se a operação eventualmente for bem-sucedida ou não, quando o resultado tiver sido determinado, FD_CONNECT ocorrerá. O cliente deve marcar o código de erro para determinar se o resultado foi bem-sucedido ou falhou.
-
FD_CLOSE: válido somente em soquetes orientados à conexão (por exemplo, SOCK_STREAM)
- Quando WSAAsyncSelect chamado, se a conexão de soquete tiver sido fechada.
- Após o fechamento normal do sistema remoto, quando nenhum dado disponível para receber no momento (lembre-se de que, se os dados tiverem sido recebidos e estiverem aguardando para serem lidos quando o sistema remoto iniciar um fechamento normal, o FD_CLOSE não será entregue até que todos os dados pendentes sejam lidos).
- Depois que o sistema local iniciar o fechamento normal com o desligamento e o sistema remoto tiver respondido com a notificação "Fim dos Dados" (por exemplo, TCP FIN), quando nenhum dado disponível para receber no momento.
- Quando o sistema remoto encerra a conexão (por exemplo, TCP RST enviado), e lParam conterá o valor de erro WSAECONNRESET .
ObservaçãoFD_CLOSE não é postado depois que closesocket é chamado.
-
FD_QOS:
- Quando WSAAsyncSelect chamado, se a qualidade do serviço associado ao soquete tiver sido alterada.
- Após o WSAIoctl com SIO_GET_QOS chamado, quando a qualidade do serviço é alterada.
- FD_GROUP_QOS: Reservado.
-
FD_ROUTING_INTERFACE_CHANGE:
- Depois que o WSAIoctl com SIO_ROUTING_INTERFACE_CHANGE chamado, quando a interface local que deve ser usada para alcançar o destino especificado no IOCTL é alterada.
-
FD_ADDRESS_LIST_CHANGE:
- Após o WSAIoctl com SIO_ADDRESS_LIST_CHANGE chamado, quando a lista de endereços locais aos quais o aplicativo pode associar alterações.
Requisitos
Requisito | Valor |
---|---|
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] |
Plataforma de Destino | Windows |
Cabeçalho | winsock.h (inclua Winsock2.h) |
Biblioteca | Ws2_32.lib |
DLL | Ws2_32.dll |