Função WSAEventSelect (winsock2.h)
A função WSAEventSelect especifica um objeto de evento a ser associado ao conjunto especificado de eventos de rede FD_XXX.
Sintaxe
int WSAAPI WSAEventSelect(
[in] SOCKET s,
[in] WSAEVENT hEventObject,
[in] long lNetworkEvents
);
Parâmetros
[in] s
Um descritor que identifica o soquete.
[in] hEventObject
Um identificador que identifica o objeto de evento a ser associado ao conjunto especificado de FD_XXX eventos de rede.
[in] lNetworkEvents
Uma máscara de bits que especifica a combinação de FD_XXX eventos de rede nos quais o aplicativo tem interesse.
Retornar valor
O valor retornado será zero se a especificação do aplicativo dos eventos de rede e o objeto de evento associado tiver sido bem-sucedido. Caso contrário, o valor SOCKET_ERROR será retornado e um número de erro específico poderá ser recuperado chamando WSAGetLastError.
Como no caso das funções select e WSAAsyncSelect , WSAEventSelect será frequentemente usado para determinar quando uma operação de transferência de dados (enviar ou rev) pode ser emitida com a expectativa de sucesso imediato. No entanto, um aplicativo robusto deve ser preparado para a possibilidade de que o objeto de evento esteja definido e emita uma chamada do Windows Sockets que retorna WSAEWOULDBLOCK imediatamente. Por exemplo, a seguinte sequência de operações é possível:
- Os dados chegam no soquete s; O Windows Sockets define o objeto de evento WSAEventSelect .
- O aplicativo faz algum outro processamento.
- Durante o processamento, o aplicativo emite um ioctlsocket(s, FIONREAD...) e percebe que há dados prontos para serem lidos.
- O aplicativo emite um recv(s,...) para ler os dados.
- O aplicativo eventualmente aguarda o objeto de evento especificado em WSAEventSelect, que retorna imediatamente indicando que os dados estão prontos para leitura.
- O aplicativo emite recv(s,...), que falha com o erro WSAEWOULDBLOCK.
Evento de rede | Reabilitando a função |
---|---|
|
A função recv, recvfrom, WSARecv, WSARecvEx ou WSARecvFrom . |
|
A função send, sendto, WSASend ou WSASendTo . |
|
A função recv, recvfrom, WSARecv, WSARecvEx ou WSARecvFrom . |
|
A função accept, AcceptEx ou WSAAccept , a menos que o código de erro retornado seja WSATRY_AGAIN indicando que a função de condição retornada CF_DEFER. |
|
Nenhum. |
|
Nenhum. |
|
A função WSAIoctl com SIO_GET_QOS de comando. |
|
Reservado. |
|
A função WSAIoctl com SIO_ROUTING_INTERFACE_CHANGE de comando. |
|
A função WSAIoctl com SIO_ADDRESS_LIST_CHANGE de comando. |
Qualquer chamada para a rotina de reassovamento, mesmo que falhe, resulta em nova detecção de gravação e sinalização para o evento de rede relevante e o objeto de evento.
Para eventos de rede FD_READ, FD_OOB e FD_ACCEPT, a gravação de eventos de rede e a sinalização de objeto de evento são disparadas em nível. Isso significa que, se a rotina de reação for chamada e a condição de rede relevante ainda for válida após a chamada, o evento de rede será registrado e o objeto de evento associado será definido. 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:
- O provedor de transporte recebe 100 bytes de dados em soquetes e faz com que WS2_32.DLL registrem o evento de rede FD_READ e defina o objeto de evento associado.
- O aplicativo emite recv(s, buffptr, 50, 0) para ler 50 bytes.
- O provedor de transporte faz com que WS2_32.DLL registre o evento de rede FD_READ e define o objeto de evento associado novamente, pois ainda há dados a serem lidos.
O evento FD_QOS é considerado gatilho de 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 renegociar a qualidade do serviço para o soquete.
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 reemita o IOCTL e outra alteração seja detectada desde que o IOCTL tenha sido emitido.
Se um evento de rede já tiver acontecido quando o aplicativo chamar WSAEventSelect ou quando a função de nova inicialização for chamada, um evento de rede será registrado e o objeto de evento associado será definido conforme apropriado. Por exemplo, considere a seguinte sequência:
- Um aplicativo chama listen.
- Uma solicitação de conexão é recebida, mas ainda não foi aceita.
- O aplicativo chama WSAEventSelect especificando que ele está interessado no evento de rede FD_ACCEPT para o soquete. Devido à persistência de eventos de rede, o Windows Sockets registra o evento de rede FD_ACCEPT e define o objeto de evento associado imediatamente.
O evento de rede 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 e obterá FD_READ evento de rede, não FD_OOB evento de rede. 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 um evento de rede FD_CLOSE indica se o fechamento do soquete foi normal ou abortivo. Se o código de erro for zero, o fechamento será normal; se o código de erro for WSAECONNRESET, o circuito virtual do soquete foi redefinido. Isso só se aplica a soquetes orientados à conexão, como SOCK_STREAM.
O evento de rede FD_CLOSE é registrado quando uma indicação próxima é recebida para o circuito virtual correspondente ao soquete. Em termos TCP, isso significa que o FD_CLOSE é registrado 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 em um closesocket. FD_CLOSE ser postado depois que todos os dados são lidos de um soquete. Um aplicativo deve marcar para os dados restantes após o recebimento de FD_CLOSE para evitar qualquer possibilidade de perda de dados. Para obter mais informações, consulte a seção sobre Desligamento Normal, Opções Persistentes e Fechamento de Soquete e a função de desligamento .
Observe que o Windows Sockets gravará apenas um evento de rede FD_CLOSE para indicar o fechamento de um circuito virtual. Ele não gravará um evento de rede FD_READ para indicar essa condição.
O evento de rede FD_QOS ou FD_GROUP_QOS é registrado quando qualquer parâmetro na especificação de fluxo associado a soquetes. Os aplicativos devem usar WSAIoctl com SIO_GET_QOS de comando para obter a qualidade atual do serviço para soquetes s.
O evento de rede FD_ROUTING_INTERFACE_CHANGE é registrado quando a interface local que deve ser usada para alcançar o destino especificado em WSAIoctl com SIO_ROUTING_INTERFACE_CHANGE alterações após a emissão desse IOCTL.
O evento de rede FD_ADDRESS_LIST_CHANGE é registrado quando a lista de endereços da família de protocolos para o soquete ao qual o aplicativo pode associar alterações após o WSAIoctl com SIO_ADDRESS_LIST_CHANGE tiver sido emitido.
Código do erro | Significado |
---|---|
WSANOTINITIALISED | Uma chamada WSAStartup bem-sucedida deve ocorrer antes de usar essa função. |
WSAENETDOWN | O subsistema de rede falhou. |
WSAEINVAL | Um dos parâmetros especificados era inválido ou o soquete especificado está em um estado inválido. |
WSAEINPROGRESS | Uma chamada de bloqueio do Windows Sockets 1.1 está em andamento ou o provedor de serviços ainda está processando uma função de retorno de chamada. |
WSAENOTSOCK | O descritor não é um soquete. |
Comentários
A função WSAEventSelect é usada para especificar um objeto de evento, hEventObject, a ser associado ao FD_XXX eventos de rede selecionados, lNetworkEvents. O soquete para o qual um objeto de evento é especificado é identificado pelo parâmetro s . O objeto de evento é definido quando ocorrem qualquer um dos eventos de rede indicados.
A função WSAEventSelect opera de forma muito semelhante a WSAAsyncSelect, sendo a diferença as ações executadas quando ocorre um evento de rede indicado. A função WSAAsyncSelect faz com que uma mensagem do Windows especificada pelo aplicativo seja postada. O WSAEventSelect define o objeto de evento associado e registra a ocorrência desse evento em um registro de evento de rede interno. Um aplicativo pode usar WSAWaitForMultipleEvents para aguardar ou sondar o objeto de evento e usar WSAEnumNetworkEvents para recuperar o conteúdo do registro de evento de rede interno e, portanto, determinar qual dos eventos de rede indicados ocorreu.
A maneira adequada de redefinir o estado de um objeto de evento usado com a função WSAEventSelect é passar o identificador do objeto de evento para a função WSAEnumNetworkEvents no parâmetro hEventObject . Isso redefinirá o objeto de evento e ajustará o status de eventos FD ativos no soquete de maneira atômica.
WSAEventSelect é a única função que faz com que a atividade de rede e os erros sejam registrados e recuperáveis por meio de WSAEnumNetworkEvents. Confira as descrições de select e WSAAsyncSelect para descobrir como essas funções relatam erros e atividades de rede.
A função WSAEventSelect define automaticamente o soquete s para o modo sem bloqueio, independentemente do valor de lNetworkEvents. Para definir o soquete de volta para o modo de bloqueio, primeiro é necessário limpar o registro de evento associado ao soquete s por meio de uma chamada para WSAEventSelect com lNetworkEvents definido como zero e o parâmetro hEventObject definido como NULL. Em seguida, você pode chamar ioctlsocket ou WSAIoctl para definir o soquete de volta para o modo de bloqueio.
O parâmetro lNetworkEvents é construído usando o operador OR bit a bit com qualquer um dos valores especificados na lista a seguir.
Valor | Significado |
---|---|
FD_READ | Deseja receber uma 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 uma notificação de conexões de entrada. |
FD_CONNECT | Deseja receber uma notificação de conexão concluída ou 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 soquete (alterações de QoS. |
FD_GROUP_QOS | Reservado para uso futuro com grupos de soquetes. Deseja receber uma notificação de alterações de QoS do grupo de soquetes. |
FD_ROUTING_ INTERFACE_CHANGE | Deseja receber uma notificação de alterações de interface de roteamento para o destino especificado. |
FD_ADDRESS_ LIST_CHANGE | Deseja receber uma notificação de alterações na lista de endereços local para a família de endereços do soquete. |
A emissão de um WSAEventSelect para um soquete cancela qualquer WSAAsyncSelect ou WSAEventSelect anterior para o mesmo soquete e limpa o registro de evento de rede interno. Por exemplo, para associar um objeto de evento a eventos de rede de leitura e gravação, o aplicativo deve chamar WSAEventSelect com FD_READ e FD_WRITE, da seguinte maneira:
rc = WSAEventSelect(s, hEventObject, FD_READ|FD_WRITE);
Não é possível especificar objetos de evento diferentes para eventos de rede diferentes. O código a seguir não funcionará; a segunda chamada cancelará os efeitos do primeiro e somente o evento de rede FD_WRITE será associado a hEventObject2:
rc = WSAEventSelect(s, hEventObject1, FD_READ);
rc = WSAEventSelect(s, hEventObject2, FD_WRITE); //bad
Para cancelar a associação e a seleção de eventos de rede em um soquete, lNetworkEvents deve ser definido como zero; nesse caso, o parâmetro hEventObject será ignorado.
rc = WSAEventSelect(s, hEventObject, 0);
Fechar um soquete com closesocket também cancela a associação e a seleção de eventos de rede especificados em WSAEventSelect para o soquete. O aplicativo, no entanto, ainda deve chamar WSACloseEvent para fechar explicitamente o objeto de evento e liberar todos os recursos.
O soquete criado quando a função accept é chamada tem as mesmas propriedades que o soquete de escuta usado para aceitá-lo. Qualquer associação WSAEventSelect e a seleção de eventos de rede definidas para o soquete de escuta se aplicam ao soquete aceito. Por exemplo, se um soquete de escuta tiver a associação WSAEventSelect de hEventObject com FD_ACCEPT, FD_READ e FD_WRITE, qualquer soquete aceito nesse soquete de escuta também terá FD_ACCEPT, FD_READ e FD_WRITE eventos de rede associados ao mesmo hEventObject. Se um hEventObject ou eventos de rede diferentes forem desejados, o aplicativo deverá chamar WSAEventSelect, passando o soquete aceito e as novas informações desejadas.
Código de exemplo
O exemplo a seguir demonstra o uso da função WSAEventSelect .//-------------------------
// Declare and initialize variables
SOCKET ListenSocket;
WSAEVENT NewEvent;
sockaddr_in InetAddr;
//-------------------------
// Initialize listening socket
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//-------------------------
// Bind listening socket
InetAddr.sin_family = AF_INET;
InetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InetAddr.sin_port = htons(27015);
bind (ListenSocket, (SOCKADDR *) &InetAddr, sizeof(InetAddr));
//-------------------------
// Create new event
NewEvent = WSACreateEvent();
//-------------------------
// Associate event types FD_ACCEPT and FD_CLOSE
// with the listening socket and NewEvent
WSAEventSelect( ListenSocket, NewEvent, FD_ACCEPT | FD_CLOSE);
//----------------------
// Listen for incoming connection requests
// on the created socket
if (listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR)
printf("Error listening on socket.\n");
printf("Listening on socket...\n");
// Need an event handler added to handle connection requests
Windows Phone 8: essa função tem suporte para aplicativos da Windows Phone Store no Windows Phone 8 e posterior.
Windows 8.1 e Windows Server 2012 R2: essa função tem suporte para aplicativos da Windows Store em Windows 8.1, Windows Server 2012 R2 e posteriores.
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Windows 8.1, Windows Vista [aplicativos da área de trabalho | Aplicativos UWP] |
Servidor mínimo com suporte | Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP] |
Plataforma de Destino | Windows |
Cabeçalho | winsock2.h |
Biblioteca | Ws2_32.lib |
DLL | Ws2_32.dll |