Condividi tramite


Funzione WSAEventSelect (winsock2.h)

La funzione WSAEventSelect specifica un oggetto evento da associare al set specificato di eventi di rete FD_XXX.

Sintassi

int WSAAPI WSAEventSelect(
  [in] SOCKET   s,
  [in] WSAEVENT hEventObject,
  [in] long     lNetworkEvents
);

Parametri

[in] s

Descrittore che identifica il socket.

[in] hEventObject

Handle che identifica l'oggetto evento da associare al set specificato di eventi di rete FD_XXX.

[in] lNetworkEvents

Maschera di bit che specifica la combinazione di FD_XXX eventi di rete in cui l'applicazione ha interesse.

Valore restituito

Il valore restituito è zero se la specifica dell'applicazione degli eventi di rete e l'oggetto evento associato ha avuto esito positivo. In caso contrario, viene restituito il valore SOCKET_ERROR e è possibile recuperare un numero di errore specifico chiamando WSAGetLastError.

Come nel caso delle funzioni select e WSAAsyncSelect , WSAEventSelect verrà spesso usato per determinare quando un'operazione di trasferimento dati (invio o recv) può essere rilasciata con l'aspettativa di esito positivo immediato. Tuttavia, un'applicazione affidabile deve essere preparata per la possibilità che l'oggetto evento sia impostato e genera una chiamata di Windows Sockets che restituisce immediatamente WSAEWOULDBLOCK . Ad esempio, è possibile eseguire la sequenza di operazioni seguente:

  • I dati arrivano sul socket s; Windows Sockets imposta l'oggetto evento WSAEventSelect .
  • L'applicazione esegue altre elaborazioni.
  • Durante l'elaborazione, l'applicazione rilascia uno opiù ioctlsocket, FIONREAD...) e nota che i dati sono pronti per la lettura.
  • L'applicazione rilascia una o più recv(s,...) per leggere i dati.
  • L'applicazione attende infine l'oggetto evento specificato in WSAEventSelect, che restituisce immediatamente che i dati sono pronti per la lettura.
  • I problemi dell'applicazione restituisconoi ,..., che hanno esito negativo con l'errore WSAEWOULDBLOCK.
Dopo aver registrato correttamente l'occorrenza dell'evento di rete (impostando il bit corrispondente nel record dell'evento di rete interno) e segnalato l'oggetto evento associato, non vengono eseguite altre azioni per tale evento di rete finché l'applicazione non effettua la chiamata di funzione che riabilita in modo implicito l'impostazione dell'evento di rete e la segnalazione dell'oggetto evento associato.
Evento di rete Riabilitare la funzione
FD_READ
Funzione recv, recvfrom, WSARecv, WSARecvEx o WSARecvFrom .
FD_WRITE
Funzione send, sendto, WSASend o WSASendTo .
FD_OOB
Funzione recv, recvfrom, WSARecv, WSARecvEx o WSARecvFrom .
FD_ACCEPT
La funzione accept, AcceptEx o WSAAccept , a meno che il codice di errore restituito non sia WSATRY_AGAIN che indica che la funzione condition ha restituito CF_DEFER.
FD_CONNECT
Nessuno.
FD_CLOSE
Nessuno.
FD_QOS
Funzione WSAIoctl con il comando SIO_GET_QOS.
FD_GROUP_QOS
Riservato.
FD_ROUTING_ INTERFACE_CHANGE
Funzione WSAIoctl con il comando SIO_ROUTING_INTERFACE_CHANGE.
FD_ADDRESS_ LIST_CHANGE
Funzione WSAIoctl con comando SIO_ADDRESS_LIST_CHANGE.
 

Qualsiasi chiamata alla routine di ripetizione, anche quella che ha esito negativo, comporta la ripetizione della registrazione e della segnalazione per l'evento di rete e l'oggetto evento pertinenti.

Per FD_READ, FD_OOB e FD_ACCEPT eventi di rete, la registrazione degli eventi di rete e la segnalazione di oggetti evento vengono attivati a livello. Ciò significa che se la routine di ripetizione viene chiamata e la condizione di rete pertinente è ancora valida dopo la chiamata, l'evento di rete viene registrato e viene impostato l'oggetto evento associato. Ciò consente a un'applicazione di essere guidata dagli eventi e di non preoccuparsi della quantità di dati che arrivano in qualsiasi momento. Considerare la sequenza seguente:

  1. Il provider di trasporto riceve 100 byte di dati nel socket s e fa sì che WS2_32.DLL registrare l'evento di rete FD_READ e impostare l'oggetto evento associato.
  2. I problemi dell'applicazione rev(s, buffptr, 50, 0) per leggere 50 byte.
  3. Il provider di trasporto determina WS2_32.DLL registrare l'evento di rete FD_READ e imposta nuovamente l'oggetto evento associato perché sono ancora presenti dati da leggere.
Con questa semantica, un'applicazione non deve leggere tutti i dati disponibili in risposta a un evento di rete FD_READ, un singolo recv in risposta a ogni evento di rete FD_READ è appropriato.

L'evento FD_QOS viene considerato attivato da edge. Un messaggio verrà inviato esattamente una volta quando si verifica una modifica della qualità del servizio. Altri messaggi non saranno imminenti finché il provider non rileverà un'ulteriore modifica della qualità del servizio o l'applicazione rinegozia la qualità del servizio per il socket.

Gli eventi FD_ROUTING_INTERFACE_CHANGE e FD_ADDRESS_LIST_CHANGE vengono considerati anche attivati da edge. Un messaggio verrà inviato esattamente una volta quando si verifica una modifica dopo che l'applicazione ha richiesto la notifica inviando WSAIoctl con SIO_ROUTING_INTERFACE_CHANGE o SIO_ADDRESS_LIST_CHANGE in modo corrispondente. Altri messaggi non saranno imminenti finché l'applicazione non ristampa IOCTL e viene rilevata un'altra modifica dopo l'emissione di IOCTL.

Se si è già verificato un evento di rete quando l'applicazione chiama WSAEventSelect o quando viene chiamata la funzione di reenabling, viene registrato un evento di rete e l'oggetto evento associato viene impostato come appropriato. Si consideri, ad esempio, la sequenza seguente:

  1. Un'applicazione chiama listen.
  2. Viene ricevuta una richiesta di connessione ma non ancora accettata.
  3. L'applicazione chiama WSAEventSelect specificando che è interessato all'evento di rete FD_ACCEPT per il socket. A causa della persistenza degli eventi di rete, Windows Sockets registra l'evento di rete FD_ACCEPT e imposta immediatamente l'oggetto evento associato.
L'evento di rete FD_WRITE viene gestito in modo leggermente diverso. Un evento di rete FD_WRITE viene registrato quando un socket viene connesso per la prima volta con una chiamata alla connessione, ConnectEx, WSAConnect, WSAConnectByList o WSAConnectByName o quando un socket viene accettato con la funzione accept, AcceptEx o WSAAccept e quindi dopo che un invio ha esito negativo con WSAEWOULDBLOCK e lo spazio del buffer diventa disponibile. Pertanto, un'applicazione può presupporre che gli invii siano possibili a partire dalla prima impostazione dell'evento di rete FD_WRITE e che durano fino a quando un invio restituisce WSAEWOULDBLOCK. Dopo un errore di questo tipo, l'applicazione scoprirà che gli invii sono nuovamente possibili quando viene registrato un evento di rete FD_WRITE e viene impostato l'oggetto evento associato.

L'evento di rete FD_OOB viene usato solo quando un socket è configurato per ricevere i dati OOB separatamente. Se il socket è configurato per ricevere dati OOB inline, i dati OOB (accelerati) vengono considerati come dati normali e l'applicazione deve registrare un interesse e otterrà FD_READ evento di rete, non FD_OOB evento di rete. Un'applicazione può impostare o controllare il modo in cui gestire i dati OOB usando setsockopt o getsockopt per l'opzione SO_OOBINLINE.

Il codice di errore in un evento di rete FD_CLOSE indica se la chiusura del socket è stata normale o interrotta. Se il codice di errore è zero, la chiusura era normale; se il codice di errore è WSAECONNRESET, il circuito virtuale del socket è stato reimpostato. Questo vale solo per i socket orientati alla connessione, ad esempio SOCK_STREAM.

L'evento di rete FD_CLOSE viene registrato quando viene ricevuta un'indicazione di chiusura per il circuito virtuale corrispondente al socket. In termini TCP, ciò significa che il FD_CLOSE viene registrato quando la connessione entra negli stati TIME WAIT o CLOSE WAIT. Ciò risulta dall'estremità remota che esegue un arresto sul lato di invio o un closesocket. FD_CLOSE essere inseriti dopo che tutti i dati vengono letti da un socket. Un'applicazione deve verificare la presenza di dati rimanenti al ricevimento di FD_CLOSE per evitare eventuali perdite di dati. Per altre informazioni, vedere la sezione relativa all'arresto normale, alle opzioni Linger e alla chiusura del socket e alla funzione di arresto .

Si noti che Windows Sockets registrerà solo un evento di rete FD_CLOSE per indicare la chiusura di un circuito virtuale. Non registrerà un evento di rete FD_READ per indicare questa condizione.

L'evento di rete FD_QOS o FD_GROUP_QOS viene registrato quando qualsiasi parametro nella specifica del flusso associata a socket s. Le applicazioni devono usare WSAIoctl con il comando SIO_GET_QOS per ottenere la qualità corrente del servizio per socket s.

L'evento di rete FD_ROUTING_INTERFACE_CHANGE viene registrato quando l'interfaccia locale da usare per raggiungere la destinazione specificata in WSAIoctl con SIO_ROUTING_INTERFACE_CHANGE modifiche dopo l'emissione di tale IOCTL.

L'evento di rete FD_ADDRESS_LIST_CHANGE viene registrato quando l'elenco di indirizzi della famiglia di protocolli per il socket in cui l'applicazione può associare le modifiche dopo l'emissione di WSAIoctl con SIO_ADDRESS_LIST_CHANGE .

Codice di errore Significato
WSANOTINITIALISED Prima di usare questa funzione, è necessario che venga eseguita una chiamata WSAStartup riuscita.
WSAENETDOWN Il sottosistema di rete non è riuscito.
WSAEINVAL Uno dei parametri specificati non è valido oppure il socket specificato è in uno stato non valido.
WSAEINPROGRESS È in corso una chiamata di Windows Sockets 1.1 bloccante oppure il provider di servizi sta ancora elaborando una funzione di callback.
WSAENOTSOCK Il descrittore non è un socket.

Commenti

La funzione WSAEventSelect viene usata per specificare un oggetto evento , hEventObject, da associare all'FD_XXX eventi di rete selezionati, lNetworkEvents. Il socket per il quale viene specificato un oggetto evento è identificato dal parametro s . L'oggetto evento viene impostato quando si verifica uno degli eventi di rete designati.

La funzione WSAEventSelect funziona in modo molto simile a WSAAsyncSelect, la differenza è quella eseguita quando si verifica un evento di rete designato. La funzione WSAAsyncSelect causa la pubblicazione di un messaggio di Windows specificato dall'applicazione. WSAEventSelect imposta l'oggetto evento associato e registra l'occorrenza di questo evento in un record di eventi di rete interno. Un'applicazione può usare WSAWaitForMultipleEvents per attendere o eseguire il polling sull'oggetto evento e usare WSAEnumNetworkEvents per recuperare il contenuto del record eventi di rete interno e quindi determinare quale degli eventi di rete designati si sono verificati.

Il modo corretto per reimpostare lo stato di un oggetto evento usato con la funzione WSAEventSelect consiste nel passare l'handle dell'oggetto evento alla funzione WSAEnumNetworkEvents nel parametro hEventObject . Verrà reimpostato l'oggetto evento e lo stato degli eventi FD attivi sul socket in modo atomico.

WSAEventSelect è l'unica funzione che causa la registrazione e gli errori di rete e il recupero tramite WSAEnumNetworkEvents. Vedere le descrizioni di select e WSAAsyncSelect per scoprire in che modo tali funzioni segnalano le attività e gli errori di rete.

La funzione WSAEventSelect imposta automaticamente socket s su modalità non bloccante, indipendentemente dal valore di lNetworkEvents. Per ripristinare la modalità di blocco del socket, è prima necessario cancellare il record dell'evento associato al socket s tramite una chiamata a WSAEventSelect con lNetworkEvents impostato su zero e il parametro hEventObject impostato su NULL. È quindi possibile chiamare ioctlsocket o WSAIoctl per ripristinare la modalità di blocco del socket.

Il parametro lNetworkEvents viene costruito usando l'operatore OR bit per bit con uno dei valori specificati nell'elenco seguente.

Valore Significato
FD_READ Vuole ricevere una notifica di idoneità per la lettura.
FD_WRITE Vuole ricevere una notifica di idoneità per la scrittura.
FD_OOB Vuole ricevere la notifica dell'arrivo dei dati OOB.
FD_ACCEPT Vuole ricevere la notifica delle connessioni in ingresso.
FD_CONNECT Vuole ricevere la notifica dell'operazione di connessione o join multipoint completata.
FD_CLOSE Vuole ricevere la notifica di chiusura del socket.
FD_QOS Vuole ricevere la notifica del socket (modifiche QoS.
FD_GROUP_QOS Riservato per uso futuro con i gruppi di socket. Si vuole ricevere la notifica delle modifiche QoS del gruppo socket.
FD_ROUTING_ INTERFACE_CHANGE Vuole ricevere la notifica delle modifiche dell'interfaccia di routing per la destinazione specificata.
FD_ADDRESS_ LIST_CHANGE Vuole ricevere la notifica delle modifiche dell'elenco di indirizzi locali per la famiglia di indirizzi del socket.
 

L'emissione di un WSAEventSelect per un socket annulla qualsiasi WSAAsyncSelect o WSAEventSelect precedente per lo stesso socket e cancella il record di eventi di rete interno. Ad esempio, per associare un oggetto evento sia alla lettura che alla scrittura di eventi di rete, l'applicazione deve chiamare WSAEventSelect con FD_READ e FD_WRITE, come indicato di seguito:

rc = WSAEventSelect(s, hEventObject, FD_READ|FD_WRITE);

Non è possibile specificare oggetti evento diversi per eventi di rete diversi. Il codice seguente non funzionerà; la seconda chiamata annulla gli effetti del primo e solo l'evento di rete FD_WRITE verrà associato a hEventObject2:

rc = WSAEventSelect(s, hEventObject1, FD_READ);
rc = WSAEventSelect(s, hEventObject2, FD_WRITE); //bad

Per annullare l'associazione e la selezione di eventi di rete in un socket, lNetworkEvents deve essere impostato su zero, nel qual caso il parametro hEventObject verrà ignorato.

rc = WSAEventSelect(s, hEventObject, 0);

La chiusura di un socket con closesocket annulla anche l'associazione e la selezione di eventi di rete specificati in WSAEventSelect per il socket. L'applicazione, tuttavia, deve comunque chiamare WSACloseEvent per chiudere in modo esplicito l'oggetto evento e liberare tutte le risorse.

Il socket creato quando viene chiamata la funzione accept ha le stesse proprietà del socket di ascolto usato per accettarlo. Qualsiasi selezione di eventi di rete e di associazione WSAEventSelect impostata per il socket di ascolto si applica al socket accettato. Ad esempio, se un socket di ascolto ha l'associazione WSAEventSelect di hEventObject con FD_ACCEPT, FD_READ e FD_WRITE, qualsiasi socket accettato in tale socket in ascolto avrà anche FD_ACCEPT, FD_READ e FD_WRITE eventi di rete associati allo stesso hEventObject. Se si desiderano eventi di rete o hEventObject diversi, l'applicazione deve chiamare WSAEventSelect, passando il socket accettato e le nuove informazioni desiderate.

Codice di esempio

Nell'esempio seguente viene illustrato l'uso della funzione 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: questa funzione è supportata per le app dello Store di Windows Phone in Windows Phone 8 e versioni successive.

Windows 8.1 e Windows Server 2012 R2: questa funzione è supportata per le app di Windows Store in Windows 8.1, Windows Server 2012 R2 e versioni successive.

Requisiti

Requisito Valore
Client minimo supportato Windows 8.1, Windows Vista [app desktop | App UWP]
Server minimo supportato Windows Server 2003 [app desktop | App UWP]
Piattaforma di destinazione Windows
Intestazione winsock2.h
Libreria Ws2_32.lib
DLL Ws2_32.dll

Vedi anche

WSAAsyncSelect

WSACloseEvent

WSACreateEvent

WSAEnumNetworkEvents

WSAWaitForMultipleEvents

Funzioni Winsock

Informazioni di riferimento su Winsock

shutdown