Compartilhar via


função de retorno de chamada LPFN_CONNECTEX (mswsock.h)

A função ConnectEx estabelece uma conexão com um soquete especificado e, opcionalmente, envia dados depois que a conexão é estabelecida. A função ConnectEx só tem suporte em soquetes orientados à conexão.

Nota Essa função é uma extensão específica da Microsoft para a especificação do Windows Sockets.

 

Sintaxe

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
)
{...}

Parâmetros

[in] s

Um descritor que identifica um soquete não conectado e anteriormente associado. Confira Comentários para obter mais informações.

[in] name

Um ponteiro para
uma estrutura sockaddr que especifica o endereço ao qual se conectar. Para IPv4, o sockaddr contém AF_INET para a família de endereços, o endereço IPv4 de destino e a porta de destino. Para IPv6, a estrutura sockaddr contém AF_INET6 para a família de endereços, o endereço IPv6 de destino, a porta de destino e pode conter informações adicionais de fluxo IPv6 e id de escopo.

[in] namelen

O comprimento, em bytes, da estrutura sockaddr apontada pelo parâmetro name .

[in, optional] lpSendBuffer

Um ponteiro para o buffer a ser transferido depois que uma conexão é estabelecida. Esse parâmetro é opcional. Se a opção TCP_FASTOPEN estiver habilitada em s antes deConnectEx ser chamado, alguns desses dados poderão ser enviados durante o estabelecimento da conexão.

[in] dwSendDataLength

O comprimento, em bytes, dos dados apontados pelo parâmetro lpSendBuffer . Esse parâmetro é ignorado quando o parâmetro lpSendBuffer é NULL.

[out] lpdwBytesSent

No retorno bem-sucedido, esse parâmetro aponta para um valor DWORD que indica o número de bytes que foram enviados depois que a conexão foi estabelecida. Os bytes enviados são do buffer apontado pelo parâmetro lpSendBuffer . Esse parâmetro é ignorado quando o parâmetro lpSendBuffer é NULL.

[in] lpOverlapped

Uma estrutura OVERLAPPED usada para processar a solicitação. O parâmetro lpOverlapped deve ser especificado e não pode ser NULL.

Retornar valor

Em caso de êxito, a função ConnectEx retorna TRUE. Em caso de falha, a função retorna FALSE. Use a função WSAGetLastError para obter informações de erro estendidas. Se uma chamada para a função WSAGetLastError retornar ERROR_IO_PENDING, a operação foi iniciada com êxito e está em andamento. Nessas circunstâncias, a chamada ainda poderá falhar quando a operação sobreposta for concluída.

Se o código de erro retornado for WSAECONNREFUSED, WSAENETUNREACH ou WSAETIMEDOUT, o aplicativo poderá chamar ConnectEx, WSAConnect ou se conectar novamente no mesmo soquete.

Código do erro Descrição
WSANOTINITIALISED
Uma chamada de função WSAStartup bem-sucedida deve ocorrer antes de usar ConnectEx.
WSAENETDOWN
O subsistema de rede falhou.
WSAEADDRINUSE
O endereço local do soquete já está em uso e o soquete não foi marcado para permitir a reutilização de endereço com SO_REUSEADDR. Esse erro geralmente ocorre durante uma operação de associação , mas o erro pode ser adiado até uma chamada de função ConnectEx , se a função bind foi chamada com um endereço curinga (INADDR_ANY ou in6addr_any) especificado para o endereço IP local. Um endereço IP específico precisa ser implicitamente associado pela função ConnectEx .
WSAEALREADY
Uma chamada de função de conexão sem bloqueio, WSAConnect ou ConnectEx está em andamento no soquete especificado.
WSAEADDRNOTAVAIL
O endereço remoto não é um endereço válido, como ADDR_ANY (a função ConnectEx só tem suporte para soquetes orientados à conexão).
WSAEAFNOSUPPORT
Os endereços na família especificada não podem ser usados com este soquete.
WSAECONNREFUSED
A tentativa de conexão foi rejeitada.
WSAEFAULT
O nome, o parâmetro lpSendBuffer ou lpOverlapped não é uma parte válida do espaço de endereço do usuário ou o namelen é muito pequeno.
WSAEINVAL
O parâmetro s é um soquete de escuta ou não associado.
WSAEISCONN
O soquete já está conectado.
WSAENETUNREACH
A rede não pode ser alcançada através deste host neste momento.
WSAEHOSTUNREACH
Uma operação de soquete foi tentada em um host inacessível.
WSAENOBUFS
Nenhum espaço de buffer está disponível; o soquete não pode ser conectado.
WSAENOTSOCK
O descritor não é um soquete.
WSAETIMEDOUT
A tentativa de se conectar com o tempo limite sem estabelecer uma conexão.

Comentários

A função ConnectEx combina várias funções de soquete em uma única transição de API/kernel. As seguintes operações são executadas quando uma chamada para a função ConnectEx é concluída com êxito:

  • Uma nova conexão é estabelecida.
  • Um bloco opcional de dados é enviado depois que a conexão é estabelecida.

Para aplicativos direcionados ao Windows Vista e posteriores, considere usar a função WSAConnectByList ou WSAConnectByName que simplifica muito o design do aplicativo cliente.

A função ConnectEx só pode ser usada com soquetes orientados à conexão. O soquete passado no parâmetro s deve ser criado com um tipo de soquete de SOCK_STREAM, SOCK_RDM ou SOCK_SEQPACKET.

O parâmetro lpSendBuffer aponta para um buffer de dados a ser enviado após a conexão ser estabelecida. O parâmetro dwSendDataLength especifica o comprimento em bytes desses dados a serem enviados. Um aplicativo pode solicitar o envio de um grande buffer de dados usando o ConnectEx da mesma forma que as funções send e WSASend podem ser usadas. Mas os desenvolvedores são altamente aconselhados a não enviar um buffer enorme em uma única chamada usando ConnectEx, pois essa operação usa uma grande quantidade de recursos de memória do sistema até que todo o buffer seja enviado.

Se a função ConnectEx for bem-sucedida, uma conexão foi estabelecida e todos os dados apontados pelo parâmetro lpSendBuffer foram enviados para o endereço especificado na estrutura sockaddr apontada pelo parâmetro name .

Nota O ponteiro de função para a função ConnectEx deve ser obtido em tempo de execução fazendo uma chamada para a função WSAIoctl com o SIO_GET_EXTENSION_FUNCTION_POINTER opcode especificado. O buffer de entrada passado para a função WSAIoctl deve conter WSAID_CONNECTEX, um GUID (identificador global exclusivo) cujo valor identifica a função de extensão ConnectEx . Com êxito, a saída retornada pela função WSAIoctl contém um ponteiro para a função ConnectEx . O GUID WSAID_CONNECTEX é definido no arquivo de cabeçalho Mswsock.h .
 

A função ConnectEx usa E/S sobreposta. Como resultado, a função ConnectEx permite que um aplicativo atere um grande número de clientes com relativamente poucos threads. Por outro lado, a função WSAConnect , que não usa E/S sobreposta, geralmente requer um thread separado para atender a cada solicitação de conexão quando solicitações simultâneas são recebidas.

Nota Todas as E/S iniciadas por um determinado thread são canceladas quando esse thread é encerrado. Para soquetes sobrepostos, as operações assíncronas pendentes podem falhar se o thread for fechado antes da conclusão das operações. Consulte ExitThread para obter mais informações.

 

Os soquetes orientados à conexão geralmente não conseguem concluir a conexão imediatamente e, portanto, a operação é iniciada e a função retorna imediatamente com o erro ERROR_IO_PENDING ou WSA_IO_PENDING. Quando a operação de conexão é concluída e o êxito ou falha é alcançado, status é relatado usando o mecanismo de notificação de conclusão indicado em lpOverlapped. Assim como acontece com todas as chamadas de função sobrepostas, você pode usar eventos ou portas de conclusão como o mecanismo de notificação de conclusão. O parâmetro lpNumberOfBytesTransferred da função GetQueuedCompletionStatus ou GetOverlappedResult ou WSAGetOverlappedResult indica o número de bytes enviados na solicitação.

Quando a função ConnectEx for concluída com êxito, os identificadores de soquete poderão ser passados apenas para as seguintes funções:

Se a função TransmitFile for chamada em um soquete conectado anteriormente com sinalizadores TF_DISCONNECT e TF_REUSE_SOCKET, o soquete especificado será retornado a um estado no qual não está conectado, mas ainda vinculado. Nesses casos, o identificador do soquete pode ser passado para a função ConnectEx em seu parâmetro s , mas o soquete não pode ser reutilizado em uma chamada de função AcceptEx . Da mesma forma, o soquete aceito reutilizado usando a função TransmitFile não pode ser usado em uma chamada para ConnectEx. Observe que, no caso de um soquete reutilizado, ConnectEx está sujeito ao comportamento do transporte subjacente. Por exemplo, um soquete TCP pode estar sujeito ao estado de TIME_WAIT TCP, fazendo com que a chamada ConnectEx seja atrasada.

Quando a função ConnectEx retorna TRUE, o soquete s está no estado padrão de um soquete conectado. O soquete s não habilita propriedades ou opções definidas anteriormente até que SO_UPDATE_CONNECT_CONTEXT seja definido no soquete. Use a função setsockopt para definir a opção SO_UPDATE_CONNECT_CONTEXT.

Por exemplo:

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

int iResult = 0;

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

A função getsockopt pode ser usada com a opção de soquete SO_CONNECT_TIME para marcar se uma conexão foi estabelecida enquanto ConnectEx está em andamento. Se uma conexão tiver sido estabelecida, o valor retornado no parâmetro optval passado para a função getsockopt será o número de segundos em que o soquete foi conectado. Se o soquete não estiver conectado, o parâmetro optval retornado conterá 0xFFFFFFFF. É necessário verificar uma conexão dessa maneira para determinar se as conexões foram estabelecidas por um período de tempo sem enviar dados; Nesses casos, é recomendável que essas conexões sejam encerradas.

Por exemplo:


//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 um soquete for aberto, uma chamada setsockopt será feita e, em seguida, uma chamada sendto será feita, o Windows Sockets executará uma chamada de função de associação implícita.
 

Se o parâmetro address da estrutura sockaddr apontado no parâmetro name for todos zeros, ConnectEx retornará o erro WSAEADDRNOTAVAIL. Qualquer tentativa de reconectar uma conexão ativa falhará com o código de erro WSAEISCONN.

Quando um soquete conectado fica fechado por qualquer motivo, é recomendável que o soquete seja descartado e um novo soquete seja criado. O raciocínio para isso é que é mais seguro supor que, quando as coisas derem errado em um soquete conectado por qualquer motivo, o aplicativo deve descartar o soquete e criar o soquete necessário novamente para retornar a um ponto estável.

Se a função DisconnectEx for chamada com o sinalizador TF_REUSE_SOCKET , o soquete especificado será retornado a um estado no qual não está conectado, mas ainda está associado. Nesses casos, o identificador do soquete pode ser passado para a função ConnectEx em seu parâmetro s .

O intervalo de tempo que deve decorrer antes que o TCP possa liberar uma conexão fechada e reutilizar seus recursos é conhecido como o estado TIME_WAIT ou o estado 2MSL. Durante esse tempo, a conexão pode ser reaberta a um custo muito menor para o cliente e o servidor do que estabelecer uma nova conexão.

O comportamento de TIME_WAIT é especificado no RFC 793, o que exige que o TCP mantenha uma conexão fechada para um intervalo pelo menos igual a duas vezes o MSL (tempo de vida máximo do segmento) da rede. Quando uma conexão é liberada, seu par de soquetes e recursos internos usados para o soquete podem ser usados para dar suporte a outra conexão.

O TCP do Windows é revertido para um estado TIME_WAIT após o fechamento de uma conexão. Enquanto estiver no estado TIME_WAIT, um par de soquetes não pode ser reutilizado. O período de TIME_WAIT é configurável modificando a seguinte configuração do Registro DWORD que representa o período de TIME_WAIT em segundos.

HKEY_LOCAL_MACHINE\Sistema\Currentcontrolset\Serviços\TCPIP\Parâmetros\Tcptimedwaitdelay

Por padrão, a MSL é definida como 120 segundos. A configuração do registro TcpTimedWaitDelay assume como padrão um valor de 240 segundos, que representa 2 vezes o tempo de vida máximo do segmento de 120 segundos ou 4 minutos. No entanto, você pode usar essa entrada para personalizar o intervalo.

Reduzir o valor dessa entrada permite que o TCP libere conexões fechadas mais rapidamente, fornecendo mais recursos para novas conexões. No entanto, se o valor for muito baixo, o TCP poderá liberar recursos de conexão antes que a conexão seja concluída, exigindo que o servidor use recursos adicionais para restabelecer a conexão.

Essa configuração do Registro pode ser definida de 0 a 300 segundos.

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

Confira também

AcceptEx

DisconnectEx

ExitThread

GetOverlappedResult

GetQueuedCompletionStatus

OVERLAPPED

ReadFile

Transmitfile

Wsaconnect

WSAConnectByList

WSAConnectByName

Wsagetlasterror

Wsaioctl

WSARecv

WSASend

Wsastartup

Funções Winsock

Referência de Winsock

WriteFile

bind

Closesocket

connect

Getsockopt

Recv

send

Sendto

Setsockopt

Sockaddr