Função WSAAccept (winsock2.h)
A função WSAAccept aceita condicionalmente uma conexão com base no valor retornado de uma função de condição, fornece qualidade das especificações de fluxo de serviço e permite a transferência de dados de conexão.
Sintaxe
SOCKET WSAAPI WSAAccept(
[in] SOCKET s,
[out] sockaddr *addr,
[in, out] LPINT addrlen,
[in] LPCONDITIONPROC lpfnCondition,
[in] DWORD_PTR dwCallbackData
);
Parâmetros
[in] s
Um descritor que identifica um soquete que está escutando conexões após uma chamada para a função de escuta .
[out] addr
Um ponteiro opcional para uma estrutura sockaddr que recebe o endereço da entidade de conexão, conforme conhecido pela camada de comunicações. O formato exato do parâmetro addr é determinado pela família de endereços estabelecida quando o soquete foi criado.
[in, out] addrlen
Um ponteiro opcional para um inteiro que contém o comprimento da estrutura sockaddr apontada pelo parâmetro addr , em bytes.
[in] lpfnCondition
O endereço de uma função de condição opcional especificada pelo aplicativo que tomará uma decisão de aceitação/rejeição com base nas informações do chamador passadas como parâmetros e, opcionalmente, criará ou ingressará em um grupo de soquetes atribuindo um valor apropriado ao parâmetro de resultado g dessa função. Se esse parâmetro for NULL, nenhuma função de condição será chamada.
[in] dwCallbackData
Dados de retorno de chamada passados de volta para a função de condição especificada pelo aplicativo como o valor do parâmetro dwCallbackData passado para a função de condição. Esse parâmetro só será aplicável se o parâmetro lpfnCondition não for NULL. Esse parâmetro não é interpretado pelo Windows Sockets.
Retornar valor
Se nenhum erro ocorrer, WSAAccept retornará um valor do tipo SOCKET que é um descritor para o soquete aceito. Caso contrário, um valor de INVALID_SOCKET é retornado e um código de erro específico pode ser recuperado chamando WSAGetLastError.
O inteiro referenciado por addrlen inicialmente contém a quantidade de espaço apontada pelo complemento. No retorno, ele conterá o comprimento real em bytes do endereço retornado.
Código do erro | Significado |
---|---|
Houve uma tentativa de acesso não autorizado a um soquete conforme as permissões de acesso. Esse erro será retornado se a solicitação de conexão oferecida tiver cronometrado ou sido retirada. | |
Nenhuma conexão pôde ser estabelecida porque o computador de destino a recusou ativamente. Esse erro será retornado se a solicitação de conexão tiver sido rejeitada com força, conforme indicado no valor retornado da função de condição (CF_REJECT). | |
uma conexão existente foi fechada forçadamente pelo host remoto. Esse erro é retornado de uma conexão de entrada indicada, mas foi posteriormente encerrado pelo par remoto antes de aceitar a chamada. | |
O sistema detectou um endereço de ponteiro inválido ao tentar usar um argumento de ponteiro em uma chamada. Esse erro é retornado do parâmetro addrlen é muito pequeno ou o addr ou lpfnCondition não faz parte do espaço de endereço do usuário. | |
Uma operação de bloqueio foi interrompida por uma chamada para WSACancelBlockingCall. Esse erro será retornado se uma chamada do Windows Sockets 1.1 de bloqueio tiver sido cancelada por meio de WSACancelBlockingCall. | |
Uma operação de bloqueio está atualmente em execução. Esse erro será retornado se uma chamada do Windows Sockets 1.1 de bloqueio estiver em andamento. | |
Foi fornecido um argumento inválido. Esse erro será retornado se listen não tiver sido invocado antes de WSAAccept, o valor retornado da função de condição não for válido ou qualquer caso em que o soquete especificado esteja em um estado inválido. | |
Número excessivo de soquetes abertos. Esse erro será retornado se a fila não estiver vazia após a entrada no WSAAccept e não houver descritores de soquete disponíveis. | |
Uma operação de soquete encontrou uma rede inoperante. Esse erro será retornado se o subsistema de rede falhar. | |
Não foi possível executar uma operação em um soquete porque o sistema não tinha espaço suficiente no buffer ou porque uma fila estava cheia. Esse erro será retornado se nenhum espaço de buffer estiver disponível. | |
Houve uma tentativa de executar uma operação em algo que não é um soquete. Esse erro será retornado se o descritor de soquete passado no parâmetro s não for um soquete. | |
A família de protocolos não foi configurada no sistema ou não existe nenhuma implementação para ela. Esse erro será retornado se o soquete referenciado não for um tipo que dê suporte ao serviço orientado à conexão. | |
Não foi possível concluir imediatamente uma operação de soquete sem bloqueio. Esse erro será retornado se o soquete estiver marcado como não desbloqueado e nenhuma conexão estiver presente para ser aceita. | |
O aplicativo não chamou WSAStartup ou WSAStartup falhou. Esse erro é retornado de uma chamada bem-sucedida para a função WSAStartup que não ocorre antes de usar essa função. | |
Esse é geralmente um erro temporário durante a resolução do nome do host e significa que o servidor local não recebeu uma resposta de um servidor autorizado. Esse erro será retornado se a aceitação da solicitação de conexão tiver sido adiada conforme indicado no valor retornado da função de condição (CF_DEFER). |
Comentários
A função WSAAccept extrai a primeira conexão na fila de conexões pendentes no soquete e a verifica na função de condição, desde que a função de condição seja especificada (ou seja, não NULL). Se a função de condição retornar CF_ACCEPT, o WSAAccept criará um novo soquete. O soquete recém-criado tem as mesmas propriedades que soquetes, incluindo eventos assíncronos registrados com WSAAsyncSelect ou com WSAEventSelect. Se a função de condição retornar CF_REJECT, o WSAAccept rejeitará a solicitação de conexão. A função de condição é executada no mesmo thread que essa função e deve retornar o mais rápido possível. Se a decisão não puder ser tomada imediatamente, a função de condição deverá retornar CF_DEFER para indicar que nenhuma decisão foi tomada e nenhuma ação sobre essa solicitação de conexão deve ser tomada pelo provedor de serviços. Quando o aplicativo estiver pronto para executar uma ação na solicitação de conexão, ele invocará WSAAccept novamente e retornará CF_ACCEPT ou CF_REJECT como um valor retornado da função de condição.
Um soquete no modo padrão (bloqueio) será bloqueado até que uma conexão esteja presente quando um aplicativo chamar WSAAccept e nenhuma conexão estiver pendente na fila.
Um soquete no modo sem bloqueio (bloqueio) falha com o erro WSAEWOULDBLOCK quando um aplicativo chama WSAAccept e nenhuma conexão está pendente na fila. Depois que o WSAAccept for bem-sucedido e retornar um novo identificador de soquete, o soquete aceito não poderá ser usado para aceitar mais conexões. O soquete original permanece aberto e escuta novas solicitações de conexão.
O parâmetro addr é um parâmetro de resultado preenchido com o endereço da entidade de conexão, conforme conhecido pela camada de comunicações. O formato exato do parâmetro addr é determinado pela família de endereços na qual a comunicação está ocorrendo. O addrlen é um parâmetro value-result; inicialmente, ele deve conter a quantidade de espaço apontada pelo complemento. No retorno, ele conterá o comprimento real (em bytes) do endereço retornado. Essa chamada é usada com tipos de soquete orientados à conexão, como SOCK_STREAM. Se addr e/ou addrlen forem iguais a NULL, nenhuma informação sobre o endereço remoto do soquete aceito será retornada. Caso contrário, esses dois parâmetros serão preenchidos se a conexão for aceita com êxito.
Um protótipo da função de condição é definido no arquivo de Winsock2.h
cabeçalho como LPCONDITIONPROC, da seguinte maneira.
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
);
ConditionFunc é um espaço reservado para a função de retorno de chamada especificada pelo aplicativo. A função de condição real deve residir em um módulo de DLL ou aplicativo. Ele é exportado no arquivo de definição do módulo.
O parâmetro lpCallerId aponta para uma estrutura WSABUF que contém o endereço da entidade de conexão, em que seu parâmetro len é o comprimento do buffer em bytes e seu parâmetro buf é um ponteiro para o buffer. O lpCallerData é um parâmetro de valor que contém todos os dados do usuário. As informações nesses parâmetros são enviadas junto com a solicitação de conexão. Se nenhum dado de chamada ou identificação de chamador estiver disponível, os parâmetros correspondentes serão NULL. Muitos protocolos de rede não dão suporte a dados do chamador de tempo de conexão. Espera-se que a maioria dos protocolos de rede convencionais dê suporte a informações de identificador de chamador no momento da solicitação de conexão. A parte buf do WSABUF apontada por lpCallerId aponta para um sockaddr. A estrutura sockaddr é interpretada de acordo com sua família de endereços (normalmente, convertendo o sockaddr em algum tipo específico para a família de endereços).
O parâmetro lpSQOS faz referência às estruturas FLOWSPEC para soquetes especificados pelo chamador, um para cada direção, seguido por parâmetros específicos do provedor adicionais. Os valores de especificação de fluxo de envio ou recebimento serão ignorados conforme apropriado para quaisquer soquetes unidirecionais. Um valor NULL indica que não há qualidade de serviço fornecida pelo chamador e que nenhuma negociação é possível. Um ponteiro lpSQOS não NULL indica que uma negociação de qualidade de serviço deve ocorrer ou que o provedor está preparado para aceitar a qualidade da solicitação de serviço sem negociação.
O parâmetro lpGQOS é reservado e deve ser NULL. (reservado para uso futuro com grupos de soquetes) faz referência à estrutura FLOWSPEC para o grupo de soquetes que o chamador deve criar, uma para cada direção, seguida por parâmetros adicionais específicos do provedor. Um valor NULL para lpGQOS indica nenhuma qualidade de serviço de grupo especificada pelo chamador. As informações de qualidade do serviço poderão ser retornadas se a negociação ocorrer.
O lpCalleeId é um parâmetro que contém o endereço local da entidade conectada. A parte buf do WSABUF apontada por lpCalleeId aponta para uma estrutura sockaddr . A estrutura sockaddr é interpretada de acordo com sua família de endereços (normalmente, convertendo o sockaddr em algum tipo específico para a família de endereços, como struct sockaddr_in).
O lpCalleeData é um parâmetro de resultado usado pela função de condição para fornecer dados do usuário de volta à entidade de conexão. O lpCalleeData-len> inicialmente contém o comprimento do buffer alocado pelo provedor de serviços e apontado por lpCalleeData-buf>. Um valor zero significa que não há suporte para a passagem de dados do usuário para o chamador. A função de condição deve copiar até lpCalleeData-len> bytes de dados para lpCalleeData-buf> e, em seguida, atualizar lpCalleeData-len> para indicar o número real de bytes transferidos. Se nenhum dado do usuário for passado de volta para o chamador, a função de condição deverá definir lpCalleeData-len> como zero. O formato de todos os dados de endereço e de usuário é específico para a família de endereços à qual o soquete pertence.
O parâmetro g é atribuído dentro da função de condição para indicar qualquer uma das seguintes ações:
- Se g for um identificador de grupo de soquetes existente, adicione s a esse grupo, desde que todos os requisitos definidos por esse grupo sejam atendidos.
- Se g = SG_UNCONSTRAINED_GROUP, crie um grupo de soquetes não treinado e tenha s como o primeiro membro.
- Se g = SG_CONSTRAINED_GROUP, crie um grupo de soquetes restrito e tenha s como o primeiro membro.
- Se g = zero, nenhuma operação de grupo será executada.
O valor do parâmetro dwCallbackData passado para a função de condição é o valor passado como o parâmetro dwCallbackData na chamada WSAAccept original. Esse valor é interpretado apenas pelo cliente do Windows Socket versão 2. Isso permite que um cliente passe algumas informações de contexto do site de chamada WSAAccept para a função de condição. Isso também fornece à função de condição quaisquer informações adicionais necessárias para determinar se a conexão deve ser aceita ou não. Um uso típico é passar um ponteiro (adequadamente convertido) para uma estrutura de dados que contém referências a objetos definidos pelo aplicativo com os quais esse soquete está associado.
Código de exemplo
O exemplo a seguir demonstra o uso da função WSAAccept .#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: 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 |
Confira também
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de