LPFN_CONNECTEX funzione di callback (mswsock.h)

La funzione ConnectEx stabilisce una connessione a un socket specificato e, facoltativamente, invia i dati una volta stabilita la connessione. La funzione ConnectEx è supportata solo nei socket orientati alla connessione.

Nota Questa funzione è un'estensione specifica di Microsoft per la specifica di Windows Sockets.

 

Sintassi

LPFN_CONNECTEX LpfnConnectex;

BOOL LpfnConnectex(
  [in]           SOCKET s,
  [in]           const sockaddr *name,
  [in]           int namelen,
  [in, optional] PVOID lpSendBuffer,
  [in]           DWORD dwSendDataLength,
  [out]          LPDWORD lpdwBytesSent,
  [in]           LPOVERLAPPED lpOverlapped
)
{...}

Parametri

[in] s

Descrittore che identifica un socket non connesso e associato in precedenza. Per ulteriori informazioni, vedere la sezione Osservazioni.

[in] name

Puntatore a
struttura sockaddr che specifica l'indirizzo a cui connettersi. Per IPv4, sockaddr contiene AF_INET per la famiglia di indirizzi, l'indirizzo IPv4 di destinazione e la porta di destinazione. Per IPv6, la struttura sockaddr contiene AF_INET6 per la famiglia di indirizzi, l'indirizzo IPv6 di destinazione, la porta di destinazione e possono contenere informazioni aggiuntive sul flusso IPv6 e sull'ID ambito.

[in] namelen

Lunghezza, in byte, della struttura sockaddr a cui punta il parametro name .

[in, optional] lpSendBuffer

Puntatore al buffer da trasferire dopo la creazione di una connessione. Questo parametro è facoltativo e, Se l'opzione TCP_FASTOPEN è abilitata in s prima della chiamata a ConnectEx , alcuni di questi dati possono essere inviati durante la creazione della connessione.

[in] dwSendDataLength

Lunghezza, in byte, dei dati a cui punta il parametro lpSendBuffer . Questo parametro viene ignorato quando il parametro lpSendBuffer è NULL.

[out] lpdwBytesSent

In caso di esito positivo, questo parametro punta a un valore DWORD che indica il numero di byte inviati dopo che è stata stabilita la connessione. I byte inviati provengono dal buffer a cui punta il parametro lpSendBuffer . Questo parametro viene ignorato quando il parametro lpSendBuffer è NULL.

[in] lpOverlapped

Struttura OVERLAPPED utilizzata per elaborare la richiesta. Il parametro lpOverlapped deve essere specificato e non può essere NULL.

Valore restituito

In caso di esito positivo, la funzione ConnectEx restituisce TRUE. In caso di errore, la funzione restituisce FALSE. Usare la funzione WSAGetLastError per ottenere informazioni estese sull'errore. Se una chiamata alla funzione WSAGetLastError restituisce ERROR_IO_PENDING, l'operazione è stata avviata correttamente ed è in corso. In tali circostanze, la chiamata potrebbe comunque non riuscire al termine dell'operazione sovrapposta.

Se il codice di errore restituito è WSAECONNREFUSED, WSAENETUNREACH o WSAETIMEDOUT, l'applicazione può chiamare ConnectEx, WSAConnect o connettersi di nuovo sullo stesso socket.

Codice di errore Descrizione
WSANOTINITIALISED
Prima di usare ConnectEx, è necessario che venga eseguita una chiamata di funzione WSAStartup riuscita.
WSAENETDOWN
Il sottosistema di rete non è riuscito.
WSAEADDRINUSE
L'indirizzo locale del socket è già in uso e il socket non è stato contrassegnato per consentire il riutilizzo degli indirizzi con SO_REUSEADDR. Questo errore si verifica in genere durante un'operazione di associazione , ma l'errore potrebbe essere ritardato fino a quando non viene chiamata una chiamata di funzione ConnectEx , se la funzione di associazione è stata chiamata con un indirizzo jolly (INADDR_ANY o in6addr_any) specificato per l'indirizzo IP locale. Un indirizzo IP specifico deve essere associato in modo implicito dalla funzione ConnectEx .
WSAEALREADY
Una chiamata di funzione Connect, WSAConnect o ConnectEx non bloccante è in corso sul socket specificato.
WSAEADDRNOTAVAIL
L'indirizzo remoto non è un indirizzo valido, ad esempio ADDR_ANY (la funzione ConnectEx è supportata solo per i socket orientati alla connessione).
WSAEAFNOSUPPORT
Impossibile utilizzare gli indirizzi della famiglia specificata con questo socket.
WSAECONNREFUSED
Il tentativo di connessione è stato rifiutato.
WSAEFAULT
Il nome, lpSendBuffer o il parametro lpOverlapped non è una parte valida dello spazio indirizzi utente o namelen è troppo piccolo.
WSAEINVAL
Il parametro s è un socket non associato o in ascolto.
WSAEISCONN
Il socket è già connesso.
WSAENETUNREACH
Impossibile raggiungere la rete da questo host in questo momento.
WSAEHOSTUNREACH
Tentativo di operazione del socket verso un host non raggiungibile.
WSAENOBUFS
Non è disponibile spazio buffer; il socket non può essere connesso.
WSAENOTSOCK
Il descrittore non è un socket.
WSAETIMEDOUT
Tentativo di connessione timeout senza stabilire una connessione.

Commenti

La funzione ConnectEx combina diverse funzioni socket in una singola transizione API/kernel. Quando una chiamata alla funzione ConnectEx viene completata correttamente, vengono eseguite le operazioni seguenti:

  • Viene stabilita una nuova connessione.
  • Un blocco facoltativo di dati viene inviato dopo aver stabilito la connessione.

Per le applicazioni destinate a Windows Vista e versioni successive, è consigliabile usare la funzione WSAConnectByList o WSAConnectByName che semplifica notevolmente la progettazione dell'applicazione client.

La funzione ConnectEx può essere usata solo con socket orientati alla connessione. Il socket passato nel parametro s deve essere creato con un tipo di socket di SOCK_STREAM, SOCK_RDM o SOCK_SEQPACKET.

Il parametro lpSendBuffer punta a un buffer di dati da inviare dopo la connessione. Il parametro dwSendDataLength specifica la lunghezza in byte di questi dati da inviare. Un'applicazione può richiedere di inviare un buffer di dati di grandi dimensioni usando ConnectEx nello stesso modo in cui è possibile usare le funzioni send e WSASend . Tuttavia, gli sviluppatori sono fortemente sconsigliati di inviare un buffer enorme in una singola chiamata tramite ConnectEx, perché questa operazione usa una grande quantità di risorse di memoria di sistema fino a quando non viene inviato l'intero buffer.

Se la funzione ConnectEx ha esito positivo, è stata stabilita una connessione e tutti i dati a cui punta il parametro lpSendBuffer è stato inviato all'indirizzo specificato nella struttura sockaddr a cui punta il parametro name .

Nota Il puntatore di funzione per la funzione ConnectEx deve essere ottenuto in fase di esecuzione effettuando una chiamata alla funzione WSAIoctl con il codice operativo SIO_GET_EXTENSION_FUNCTION_POINTER specificato. Il buffer di input passato alla funzione WSAIoctl deve contenere WSAID_CONNECTEX, un identificatore univoco globale (GUID) il cui valore identifica la funzione di estensione ConnectEx . In caso di esito positivo, l'output restituito dalla funzione WSAIoctl contiene un puntatore alla funzione ConnectEx . Il GUID WSAID_CONNECTEX è definito nel file di intestazione Mswsock.h .
 

La funzione ConnectEx usa operazioni di I/O sovrapposte. Di conseguenza, la funzione ConnectEx consente a un'applicazione di gestire un numero elevato di client con pochi thread. Al contrario, la funzione WSAConnect , che non usa operazioni di I/O sovrapposte, richiede in genere un thread separato per gestire ogni richiesta di connessione quando vengono ricevute richieste simultanee.

Nota Tutte le operazioni di I/O avviate da un determinato thread vengono annullate quando il thread viene chiuso. Per i socket sovrapposti, le operazioni asincrone in sospeso possono avere esito negativo se il thread viene chiuso prima del completamento delle operazioni. Per altre informazioni, vedere ExitThread .

 

I socket orientati alla connessione spesso non sono in grado di completare immediatamente la connessione e pertanto l'operazione viene avviata e la funzione restituisce immediatamente con l'errore ERROR_IO_PENDING o WSA_IO_PENDING. Al termine dell'operazione di connessione e l'esito positivo o negativo, lo stato viene segnalato usando il meccanismo di notifica di completamento indicato in lpOverlapped. Come per tutte le chiamate di funzione sovrapposte, è possibile usare eventi o porte di completamento come meccanismo di notifica di completamento. Il parametro lpNumberOfBytesTransferred della funzione GetQueuedCompletionStatus o GetOverlappedResult o WSAGetOverlappedResult indica il numero di byte inviati nella richiesta.

Al termine della funzione ConnectEx , l'handle del socket può essere passato solo alle funzioni seguenti:

Se la funzione TransmitFile viene chiamata su un socket connesso in precedenza con flag sia TF_DISCONNECT che TF_REUSE_SOCKET, il socket specificato viene restituito a uno stato in cui non è connesso, ma ancora associato. In questi casi, l'handle del socket può essere passato alla funzione ConnectExnel relativo parametro , ma il socket non può essere riutilizzato in una chiamata di funzione AcceptEx . Analogamente, il socket accettato riutilizzato usando la funzione TransmitFile non può essere usato in una chiamata a ConnectEx. Si noti che nel caso di un socket riutilizzato, ConnectEx è soggetto al comportamento del trasporto sottostante. Ad esempio, un socket TCP può essere soggetto allo stato tcp TIME_WAIT, causando il ritardo della chiamata ConnectEx .

Quando la funzione ConnectEx restituisce TRUE, il socket s si trova nello stato predefinito per un socket connesso. Il socket s non abilita le proprietà o le opzioni impostate in precedenza fino a quando non viene impostato SO_UPDATE_CONNECT_CONTEXT sul socket. Usare la funzione setockopt per impostare l'opzione SO_UPDATE_CONNECT_CONTEXT.

Ad esempio:

//Need to #include <mswsock.h> for SO_UPDATE_CONNECT_CONTEXT

int iResult = 0;

iResult = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );

La funzione getsockopt può essere usata con l'opzione socket SO_CONNECT_TIME per verificare se è stata stabilita una connessione mentre ConnectEx è in corso. Se è stata stabilita una connessione, il valore restituito nel parametro optval passato alla funzione getsockopt è il numero di secondi in cui è stato connesso il socket. Se il socket non è connesso, il parametro optval restituito contiene 0xFFFFFFFF. Il controllo di una connessione in questo modo è necessario per determinare se le connessioni sono state stabilite per un periodo di tempo senza inviare dati; in questi casi, è consigliabile che tali connessioni vengano terminate.

Ad esempio:


//Need to #include <mswsock.h> for SO_CONNECT_TIME

int seconds;
int bytes = sizeof(seconds);
int iResult = 0;

iResult = getsockopt( s, SOL_SOCKET, SO_CONNECT_TIME,
                      (char *)&seconds, (PINT)&bytes );
if ( iResult != NO_ERROR ) {
    printf( "getsockopt(SO_CONNECT_TIME) failed with error: %u\n", 
        WSAGetLastError() );
}
else {
    if (seconds == 0xFFFFFFFF)
        printf("Connection not established yet\n");
    else
       printf("Connection has been established %ld seconds\n",
           seconds);
}

Nota Se viene aperto un socket, viene eseguita una chiamata setockopt e viene eseguita una chiamata sendto , Windows Sockets esegue una chiamata di funzione di associazione implicita.
 

Se il parametro di indirizzo della struttura sockaddr a cui punta nel parametro name è tutti zero, ConnectEx restituisce l'errore WSAEADDRNOTAVAIL. Qualsiasi tentativo di riconnessione di una connessione attiva avrà esito negativo con il codice di errore WSAEISCONN.

Quando un socket connesso viene chiuso per qualsiasi motivo, è consigliabile eliminare il socket e creare un nuovo socket. Il motivo per questo è che è più sicuro presupporre che quando le cose vanno in un socket connesso per qualsiasi motivo, l'applicazione deve eliminare il socket e creare di nuovo il socket necessario per tornare a un punto stabile.

Se la funzione DisconnectEx viene chiamata con il flag TF_REUSE_SOCKET , il socket specificato viene restituito a uno stato in cui non è connesso, ma ancora associato. In questi casi, l'handle del socket può essere passato alla funzione ConnectEx nel relativo parametro.

Intervallo di tempo che deve essere trascorso prima che TCP possa rilasciare una connessione chiusa e riutilizzarne le risorse è noto come stato TIME_WAIT o 2MSL. Durante questo periodo, la connessione può essere riaperta a costi molto inferiori al client e al server rispetto alla creazione di una nuova connessione.

Il comportamento TIME_WAIT viene specificato in RFC 793, che richiede che TCP gestisce una connessione chiusa per un intervallo almeno uguale a due volte la durata massima del segmento (MSL) della rete. Quando viene rilasciata una connessione, è possibile usare la coppia di socket e le risorse interne usate per il socket per supportare un'altra connessione.

Windows TCP ripristina lo stato di TIME_WAIT successiva alla chiusura di una connessione. Mentre nello stato TIME_WAIT non è possibile riutilizzare una coppia di socket. Il periodo di TIME_WAIT è configurabile modificando l'impostazione del Registro di sistema DWORD seguente che rappresenta il periodo di TIME_WAIT in secondi.

HKEY_LOCAL_MACHINE\Sistema\Currentcontrolset\Servizi\TCPIP\Parametri\TcpTimedWaitDelay

Per impostazione predefinita, msl è definito come 120 secondi. L'impostazione predefinita del Registro di sistema TcpTimedWaitDelay viene impostata su un valore pari a 240 secondi, che rappresenta 2 volte la durata massima del segmento di 120 secondi o 4 minuti. È tuttavia possibile usare questa voce per personalizzare l'intervallo.

La riduzione del valore di questa voce consente a TCP di rilasciare connessioni chiuse più velocemente, fornendo più risorse per le nuove connessioni. Tuttavia, se il valore è troppo basso, TCP potrebbe rilasciare le risorse di connessione prima del completamento della connessione, richiedendo al server di usare risorse aggiuntive per stabilire nuovamente la connessione.

Questa impostazione del Registro di sistema può essere impostata da 0 a 300 secondi.

Windows Phone 8: questa funzione è supportata per le app 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.

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 mswsock.h

Vedi anche

AcceptEx

DisconnessioneEx

ExitThread

GetOverlappedResult

GetQueuedCompletionStatus

SOVRAPPOSTA

ReadFile

Transmitfile

WSAConnect

WSAConnectByList

WSAConnectByName

WSAGetLastError

Wsaioctl

WSARecv

WSASend

WSAStartup

Funzioni Winsock

Informazioni di riferimento su Winsock

WriteFile

bind

closesocket

connect

getsockopt

Recv

send

Sendto

Setsockopt

sockaddr