Funzione WSAAccept (winsock2.h)
Il WSAAccept funzione accetta in modo condizionale una connessione in base al valore restituito di una funzione condizione, fornisce la qualità delle specifiche del flusso di servizio e consente il trasferimento dei dati di connessione.
Sintassi
SOCKET WSAAPI WSAAccept(
[in] SOCKET s,
[out] sockaddr *addr,
[in, out] LPINT addrlen,
[in] LPCONDITIONPROC lpfnCondition,
[in] DWORD_PTR dwCallbackData
);
Parametri
[in] s
Descrittore che identifica un socket in ascolto delle connessioni dopo una chiamata alla funzione listen
[out] addr
Puntatore facoltativo a un sockaddr struttura che riceve l'indirizzo dell'entità di connessione, come noto al livello di comunicazione. Il formato esatto del parametro addr
[in, out] addrlen
Puntatore facoltativo a un numero intero contenente la lunghezza del
[in] lpfnCondition
Indirizzo di una funzione di condizione facoltativa specificata dall'applicazione che effettuerà una decisione di accettazione/rifiuto in base alle informazioni del chiamante passate come parametri e, facoltativamente, creare o unire un gruppo di socket assegnando un valore appropriato al parametro result g di questa funzione. Se questo parametro è NULL, non viene chiamata alcuna funzione condizione.
[in] dwCallbackData
I dati di callback passati alla funzione condizione specificata dall'applicazione come valore del parametro dwCallbackData passato alla funzione condition. Questo parametro è applicabile solo se il parametro
Valore restituito
Se non si verifica alcun errore, WSAAccept restituisce un valore di tipo SOCKET che è un descrittore per il socket accettato. In caso contrario, viene restituito un valore di INVALID_SOCKET e un codice di errore specifico può essere recuperato chiamando WSAGetLastError.
L'intero a cui fa riferimento addrlen inizialmente contiene la quantità di spazio a cui punta addr. In caso di restituzione, conterrà la lunghezza effettiva in byte dell'indirizzo restituito.
Codice di errore | Significato |
---|---|
È stato effettuato un tentativo di accesso a un socket in modo non consentito dalle autorizzazioni di accesso. Questo errore viene restituito se la richiesta di connessione offerta è scaduta o ritirata. | |
|
Non è stato possibile stabilire alcuna connessione perché il computer di destinazione l'ha rifiutata attivamente. Questo errore viene restituito se la richiesta di connessione è stata rifiutata forzatamente come indicato nel valore restituito della funzione condizione (CF_REJECT). |
Una connessione esistente è stata chiusa forzatamente dall'host remoto. Questo errore viene restituito di una connessione in ingresso, ma successivamente è stato terminato dal peer remoto prima di accettare la chiamata. | |
Il sistema ha rilevato un indirizzo puntatore non valido nel tentativo di usare un argomento puntatore in una chiamata. Questo errore viene restituito dal parametro |
|
Un'operazione di blocco è stata interrotta da una chiamata a WSACancelBlockingCall. Questo errore viene restituito se una chiamata bloccante di Windows Sockets 1.1 è stata annullata tramite WSACancelBlockingCall. | |
Un'operazione di blocco è attualmente in esecuzione. Questo errore viene restituito se è in corso una chiamata di Windows Sockets 1.1 bloccante. | |
È stato fornito un argomento non valido. Questo errore viene restituito se listen non è stato richiamato prima di WSAAccept, il valore restituito della funzione della condizione non è valido o in qualsiasi caso in cui il socket specificato si trova in uno stato non valido. | |
Troppi socket aperti. Questo errore viene restituito se la coda non è in attesa di immissione per WSAAccept e non sono disponibili descrittori socket. | |
Un'operazione socket ha rilevato una rete inattiva. Questo errore viene restituito se il sottosistema di rete non è riuscito. | |
Impossibile eseguire un'operazione su un socket perché il sistema non disponeva di spazio sufficiente nel buffer o perché una coda era piena. Questo errore viene restituito se non è disponibile spazio nel buffer. | |
È stata tentata un'operazione su un elemento che non è un socket. Questo errore viene restituito se il descrittore socket passato nel parametro |
|
La famiglia di protocolli non è stata configurata nel sistema o non esiste alcuna implementazione. Questo errore viene restituito se il socket a cui si fa riferimento non è un tipo che supporta il servizio orientato alla connessione. | |
Impossibile completare immediatamente un'operazione socket non bloccabile. Questo errore viene restituito se il socket è contrassegnato come non bloccante e non sono presenti connessioni da accettare. | |
L'applicazione non ha chiamato WSAStartupo WSAStartup. Questo errore viene restituito di una chiamata riuscita al WSAStartup funzione dit non si verificano prima di usare questa funzione. | |
Si tratta in genere di un errore temporaneo durante la risoluzione del nome host e indica che il server locale non ha ricevuto una risposta da un server autorevole. Questo errore viene restituito se l'accettazione della richiesta di connessione è stata posticipata come indicato nel valore restituito della funzione condizione (CF_DEFER). |
Osservazioni
La funzione WSAAccept estrae la prima connessione nella coda di connessioni in sospeso sul socket e la controlla rispetto alla funzione condizione, purché venga specificata la funzione condizione , ovvero non NULL). Se la funzione della condizione restituisce CF_ACCEPT, WSAAccept crea un nuovo socket. Il socket appena creato ha le stesse proprietà del socket
Un socket in modalità predefinita (blocco) bloccherà finché non è presente una connessione quando un'applicazione chiama WSAAccept e nessuna connessione è in sospeso nella coda.
Un socket in modalità non bloccante (blocco) ha esito negativo con l'errore WSAEWOULDBLOCK quando un'applicazione chiama WSAAccept e non sono presenti connessioni in sospeso nella coda. Dopo WSAAccept ha esito positivo e restituisce un nuovo handle socket, il socket accettato non può essere usato per accettare altre connessioni. Il socket originale rimane aperto e rimane in ascolto delle nuove richieste di connessione.
Il parametro addr
Un prototipo della funzione condizione viene definito nel file di intestazione Winsock2.h
come LPCONDITIONPROC, come indicato di seguito.
int CALLBACK
ConditionFunc(
IN LPWSABUF lpCallerId,
IN LPWSABUF lpCallerData,
IN OUT LPQOS lpSQOS,
IN OUT LPQOS lpGQOS,
IN LPWSABUF lpCalleeId,
IN LPWSABUF lpCalleeData,
OUT GROUP FAR * g,
IN DWORD_PTR dwCallbackData
);
Il ConditionFunc
Il parametro lpCallerId punta a una struttura WSABUF che contiene l'indirizzo dell'entità di connessione, in cui il parametro len è la lunghezza del buffer in byte e il relativo parametro buf è un puntatore al buffer. Il lpCallerData è un parametro di valore che contiene dati utente. Le informazioni contenute in questi parametri vengono inviate insieme alla richiesta di connessione. Se non sono disponibili dati di identificazione o chiamante del chiamante, i parametri corrispondenti verranno NULL. Molti protocolli di rete non supportano i dati del chiamante in fase di connessione. La maggior parte dei protocolli di rete convenzionali può essere prevista per supportare le informazioni sull'identificatore del chiamante in fase di richiesta di connessione. La parte buf del WSABUF a cui punta lpCallerId punta a un sockaddr. La struttura sockaddr
Il parametro lpSQOS
Il parametro lpGQOS
Il lpCalleeId è un parametro che contiene l'indirizzo locale dell'entità connessa. La parte buf del WSABUF a cui punta lpCalleeId punta a una struttura sockaddr. La struttura sockaddr
Il
Il parametro g viene assegnato all'interno della funzione condition per indicare una delle azioni seguenti:
- Se g è un identificatore del gruppo di socket esistente, aggiungere a questo gruppo, purché vengano soddisfatti tutti i requisiti impostati da questo gruppo.
- Se g = SG_UNCONSTRAINED_GROUP, creare un gruppo di socket non vincolato e avere come primo membro.
- Se g = SG_CONSTRAINED_GROUP, creare un gruppo di socket vincolato e avere come primo membro.
- Se g = zero, non viene eseguita alcuna operazione di gruppo.
Il valore del parametro dwCallbackData passato alla funzione condition è il valore passato come parametro dwCallbackData nella chiamata WSAAccept originale. Questo valore viene interpretato solo dal client Windows Socket versione 2. In questo modo un client può passare alcune informazioni di contesto dalla WSAAccept sito di chiamata alla funzione condition. In questo modo la funzione condizione fornisce anche eventuali informazioni aggiuntive necessarie per determinare se accettare o meno la connessione. Un utilizzo tipico consiste nel passare un puntatore (correttamente cast) a una struttura di dati contenente riferimenti a oggetti definiti dall'applicazione a cui è associato questo socket.
codice di esempio
Nell'esempio seguente viene illustrato l'uso della funzione#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
/* Define an example conditional function that depends on the pQos field */
int CALLBACK ConditionAcceptFunc(
LPWSABUF lpCallerId,
LPWSABUF lpCallerData,
LPQOS pQos,
LPQOS lpGQOS,
LPWSABUF lpCalleeId,
LPWSABUF lpCalleeData,
GROUP FAR * g,
DWORD_PTR dwCallbackData
)
{
if (pQos != NULL) {
RtlZeroMemory(pQos, sizeof(QOS));
return CF_ACCEPT;
} else
return CF_REJECT;
}
int main() {
/* Declare and initialize variables */
WSADATA wsaData;
SOCKET ListenSocket, AcceptSocket;
struct sockaddr_in saClient;
int iClientSize = sizeof(saClient);
u_short port = 27015;
char* ip;
sockaddr_in service;
int error;
/* Initialize Winsock */
error = WSAStartup(MAKEWORD(2,2), &wsaData);
if (error) {
printf("WSAStartup() failed with error: %d\n", error);
return 1;
}
/* Create a TCP listening socket */
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
printf("socket() failed with error: %d\n", WSAGetLastError() );
WSACleanup();
return 1;
}
/*-----------------------------------------
* Set up the sock addr structure that the listening socket
* will be bound to. In this case, the structure holds the
* local IP address and the port specified. */
service.sin_family = AF_INET;
service.sin_port = htons(port);
hostent* thisHost;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
service.sin_addr.s_addr = inet_addr(ip);
/*-----------------------------------------
* Bind the listening socket to the IP address.
* and port number specified by the sockaddr structure. */
error = bind(ListenSocket, (SOCKADDR *) &service, sizeof(SOCKADDR));
if (error == SOCKET_ERROR) {
printf("bind() failed with error: %d\n", WSAGetLastError() );
closesocket(ListenSocket);
WSACleanup();
return 1;
}
/* Make the socket listen for incoming connection requests */
error = listen(ListenSocket, 1);
if (error == SOCKET_ERROR) {
printf("listen() failed with error: %d\n", WSAGetLastError() );
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("Listening...\n");
/*-----------------------------------------
* Accept an incoming connection request on the
* listening socket and transfer control to the
* accepting socket. */
AcceptSocket = WSAAccept(ListenSocket, (SOCKADDR*) &saClient, &iClientSize,
&ConditionAcceptFunc, NULL);
/* Now do some work with the AcceptSocket
* At this point, the application could
* handle data transfer on the socket, or other socket
* functionality.*/
/* Then clean up and quit */
closesocket(AcceptSocket);
closesocket(ListenSocket);
WSACleanup();
return 0;
}
Windows Phone 8: Questa funzione è supportata per le app di Windows Phone Store 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.
Fabbisogno
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 | Finestre |
intestazione |
winsock2.h |
libreria |
Ws2_32.lib |
dll | Ws2_32.dll |